河北省建设厅网站6,企业推广哪个平台好,中国网站设计师联盟,外贸建站用的服务器一、过时方法
一些不推荐使用的方法已经过时#xff0c;容易破坏同步代码块#xff0c;使对象的锁得不到释放#xff0c;进而造成线程死锁
二、守护线程
默认情况下#xff0c;Java 进程需要等待所有线程都运行结束#xff0c;才会结束。有一种特殊的线程叫做守护线程…一、过时方法
一些不推荐使用的方法已经过时容易破坏同步代码块使对象的锁得不到释放进而造成线程死锁
二、守护线程
默认情况下Java 进程需要等待所有线程都运行结束才会结束。有一种特殊的线程叫做守护线程只要其它非守护线程运行结束了即使守护线程的代码没有执行完也会强制结束。
正常情况下主线程运行结束但t1线程仍未结束因此进程并不会结束只要有一个线程还在运行Java进程并不会结束
将t1设置为守护线程后
import lombok.extern.slf4j.Slf4j;Slf4j(topic c.Test15)
public class Test15 {public static void main(String[] args) throws InterruptedException {Thread t1 new Thread(() - {while (true) {if (Thread.currentThread().isInterrupted()) {break;}}log.debug(结束);}, t1);// 将t1设置为守护线程默认值为非守护线程falset1.setDaemon(true); t1.start();Thread.sleep(1000);log.debug(结束);}
}运行结果主线程(非守护)运行结束后无论守护线程(t1)是否执行完毕均会强制结束
守护线程应用 ● 垃圾回收器线程就是一种守护线程【再堆内存中分配的对象当没有其它对象引用这些对象时这些未被引用的对象就会定期被垃圾回收】 ● Tomcat 中的 Acceptor 和 Poller 线程都是守护线程所以 Tomcat 接收到 shutdown 命令后不会等待它们处理完当前请求
三、线程状态五种
五种状态这是从 操作系统 层面来描述的 ● 初始状态】仅是在语言层面创建了线程对象还未与操作系统线程关联egJava中newThread对象但未调用其start()方法
● 【可运行状态】就绪状态指该线程已经被创建与操作系统线程关联可以由 CPU 调度执行但暂时还未获得CPU的时间片
● 【运行状态】指获取了 CPU 时间片运行中的状态 —— 当 CPU 时间片用完会从【运行状态】转换至【可运行状态】其切换会导致线程的上下文切换
● 【阻塞状态】 —— 如果调用了阻塞 API如 BIO 读写文件这时该线程实际不会用到 CPU调度器不会考虑调度阻塞状态的线程会导致线程上下文切换进入【阻塞状态】 —— 等 BIO 操作完毕会由操作系统唤醒阻塞的线程转换至【可运行状态】 —— 与【可运行状态】的区别是对【阻塞状态】的线程来说只要它们一直不唤醒调度器就一直不会考虑调度它们
● 【终止状态】表示线程已经执行完毕生命周期已经结束不会再转换为其它状态
四、线程状态六种
六种状态是从Java API层面来描述的
根据Thread.State枚举分为六种状态 ● NEW 线程刚被创建但是还没有调用 start() 方法
● RUNNABLE 当调用了 start() 方法之后注意Java API 层面的 RUNNABLE 状态涵盖了 操作系统 层面的【可运行状态】、【运行状态】和【阻塞状态】由于 BIO 导致的线程阻塞在 Java 里无法区分仍然认为是可运行操作系统层面的阻塞状态在Java中还是RUNNABLE
● BLOCKED WAITING TIMED_WAITING 都是 Java API 层面对【阻塞状态】的细分后面会在状态转换一节详述
● TERMINATED 当线程代码运行结束
3.1 六种状态演示
import lombok.extern.slf4j.Slf4j;import java.io.IOException;Slf4j(topic c.TestState)
public class TestState {public static void main(String[] args) throws IOException {// ① 并未调用线程1的start()方法NEWThread t1 new Thread(t1) {Overridepublic void run() {log.debug(running...);}};// ② 不断运行RUNNABLE既有可能分到时间片也有可能为分到时间片也有可能陷入操作系统的IO阻塞Thread t2 new Thread(t2) {Overridepublic void run() {while(true) { // runnable}}};t2.start();// ③ 打印后执行完毕TERMINATEDThread t3 new Thread(t3) {Overridepublic void run() {log.debug(running...);}};t3.start();// ④ 线程处于阻塞状态【sleep时间足够长TIMED_WAITING(有时限的的等待)】Thread t4 new Thread(t4) {Overridepublic void run() {synchronized (TestState.class) {try {Thread.sleep(1000000); // timed_waiting} catch (InterruptedException e) {e.printStackTrace();}}}};t4.start();// ⑤ 等待t2死循环一直运行结束WAITING(没有时限的等待)Thread t5 new Thread(t5) {Overridepublic void run() {try {t2.join(); // waiting} catch (InterruptedException e) {e.printStackTrace();}}};t5.start();// ⑥ t4线程会先对对象加锁,t6线程不能获取对象的锁t6陷入BLOCKEDThread t6 new Thread(t6) {Overridepublic void run() {synchronized (TestState.class) { // blockedtry {Thread.sleep(1000000);} catch (InterruptedException e) {e.printStackTrace();}}}};t6.start();try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}log.debug(t1 state {}, t1.getState());log.debug(t2 state {}, t2.getState());log.debug(t3 state {}, t3.getState());log.debug(t4 state {}, t4.getState());log.debug(t5 state {}, t5.getState());log.debug(t6 state {}, t6.getState());System.in.read();}
}运行结果
四、多线程应用统筹分析
如何使用多线程得到最优方案 后两种办法均耗费时间较长 上图可以一眼看出办法甲总共要16分钟而办法乙、丙需要20分钟。因此合理分配便可节约大量时间我们可以使用多线程的思想便可找到最优的方案 方案实现
import lombok.extern.slf4j.Slf4j;import static cn.itcast.n2.util.Sleeper.sleep;Slf4j(topic c.Test16)
public class Test16 {public static void main(String[] args) {Thread t1 new Thread(() - {log.debug(洗水壶);sleep(1);log.debug(烧开水);sleep(5);},老王);Thread t2 new Thread(() - {log.debug(洗茶壶);sleep(1);log.debug(洗茶杯);sleep(2);log.debug(拿茶叶);sleep(1);try {t1.join();} catch (InterruptedException e) {e.printStackTrace();}log.debug(泡茶);},小王);t1.start();t2.start();}
}运行结果