java多线程控制_Java多线程之线程的控制

Java多线程之线程的控制

线程中的7 种非常重要的状态:

初始New、可运行Runnable、运行Running、阻塞Blocked、锁池lock_pool、等待队列wait_pool、结束Dead

如果将“锁池”和“等待队列”都看成是“阻塞”状态的特殊情况,那么可以将线程归纳为5个状态:

新建,就绪,运行,阻塞,死亡。

┌--------------------< 阻塞

↓                    (1)(2)(3)        结束

①②③        OS调度         ↑             ↑

初始-------> 可运行 ↹---------------↹ 运行 >-----------┤

t.start()启动 ↑                        ↓              ↓o.wait()

└-----< 锁池 ←---------

获得锁标志   synchronized(o)

注意:图中标记依次为

①输入完毕;    ②wake up    ③t1 退出

⑴等待输入(输入设备进行处理,而CUP 不处理),则放入阻塞,直到输入完毕。

⑵线程休眠sleep()

⑶t1.join()将t1 加入运行队列,直到t1 退出,当前线程才继续。

特别注意:①②③与⑴⑵⑶是一一对应的。

进程的休眠:Thread.sleep(1000);//括号中以毫秒为单位

当线程运行完毕,即使在结束时时间片还没有用完,CPU 也放弃此时间片,继续运行其他程序。

T1.join 实际上是把并发的线程编成并行运行。

3dc35bb8c8ff8aaeaefc03fb98eaeb56.png

实现对多线程的控制:

控制多线程,记住下面几个API就够了:

1,start方法:创建一个线程。值得注意的是,new一个线程的时候,只是表示该线程处于新建状态,并不是执行状态。使用start方法后启动一个线程,线程处于就绪状态,也并不是说直接就在运行了,它表示这个线程可以运行了,但是什么时候开始运行,取决于JVM里线程调度器的调度。

2,stop方法:结束一个线程。容易导致死锁,不推荐使用。值得注意的是,不要试图在一个线程已死亡的情况下再次调用start方法来启动该线程,会报illegalThreadStateException错的。

3,join方法:在一个线程中加入一个线程。当在某个程序执行流中调用了其他线程的join方法时,调用线程将被阻塞,直到被join方法加入的join线程完成为止。

4,sleep方法:让线程睡觉。使当前正在执行的线程暂停一段时间,并进入阻塞状态。

5,yield方法:和sleep方法相似,让当前正在执行的线程暂停一下,但是他不会阻塞这个线程,它只是将这个线程转入就绪状态。

6,setPriority方法:设置线程优先级。set和getPriority设置和获得线程的优先级,1到10一共10个数字,默认是5,数字越大优先级越高,越容易获得执行机会。 为了跨平台,最好不要使用优先级决定线程的执行顺序。这个时候使用3个静态常量:max_Priority,min_Priority,norm_Priority。

7,setDaemon方法:设置后台线程。   Daemon Threads(daemon 线程)是服务线程,当其他线程全部结束,只剩下daemon线程时,虚拟机会立即退出。

Thread t = new DaemonThread();

t.setDaemon(true);//setDaemon(true)把线程标志为daemon,其他的都跟一般线程一样

t.start();//一定要先setDaemon(true),再启动线程

在daemon线程内启动的线程,都定为daemon线程

8,wait(),Notify()方法在后面介绍同步锁的时候在仔细说。 在运行状态中,线程调用wait(),表示这线程将释放自己所有的锁标记,同时进入这个对象的等待队列。等待队列的状态也是阻塞状态,只不过线程释放自己的锁标记。用notify()方法叫出之后,紧跟着刚才wait();的位置往下执行。如果一个线程调用对象的notify(),就是通知对象等待队列的一个线程出列。进入锁池。如果使用notifyall()则通知等待队列中所有的线程出列。

有一个问题,在什么情况下,一个线程将进入阻塞状态?

1,线程调用了sleep方法,主动放弃它所占有的处理器资源

2,线程调用了阻塞式IO方法,在方法返回之前,线程阻塞了

3,线程试图获得一个同步监听器,但是该同步监视器正被其他的线程持有

4,线程在等待某一个notify通知

5,线程调用了suspend方法将线程挂起了。

要是让一个线程由阻塞状态变成了就绪状态正好和上面的情况相反,最后一点使用resume方法就好了。值得注意的是:suspend()将运行状态推到阻塞状态(注意不释放锁标记)。恢复状态用resume()。Stop()释放全部。这几个方法上都有Deprecated 标志,说明这个方法不推荐使用。一般来说,主方法main()结束的时候线程结束,可是也可能出现需要中断线程的情况。对于多线程一般每个线程都是一个循环,如果中断线程我们必须想办法使其退出。如果想结束阻塞中的线程(如sleep 或wait),可以由其他线程对其对象调用interrupt()。用于对阻塞(或锁池)会抛出例外Interrupted。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值