多线程的生命周期

实现多线程的两种方式:继承Thread类或是实现Runnable接口,推荐后者
线程所拥有的状态:初始状态,可运行状态,运行状态,阻塞状态,锁池状态,等待队列,终止状态。
线程的生命状态:
1.当线程类被创建后就进入初始化状态。
2.当调用.start()方法时就拿到对象锁,进入可运行状态(一旦获取cpu资源就会进入运行状态)
3.当处于可运行状态的线程拿到cpu分配的时间片就进入运行状态。
3.1.如果处于运行状态的线程的main方法或是run方法执行完,线程就进入终止状态。
3.2.如果当前处于运行状态的线程调用sleep()方法或是join()方法,线程就进入阻塞状态。此时不释放资源(主要指对象锁)。当睡眠时间结束后进入可运行状态,等待获取cpu的时间片。
3.3.当处于运行状态的当前线程调用yield方法,线程就会放弃当前时间片回到可运行状态。和其他线程再次竞争。
3.4.当进入运行状态的线程调用wait方法后就会进入等待状态。只有调用了notify(只唤醒一个线程不确定唤醒哪个线程)或是notifyAll方法会后进入锁池状态。拿到对象锁标记后会进入可运行状态。
3.5.当运行状态的线程发现要使用的资源被同步时,会进入锁池状态,当拿到对象锁后会进入可运行状态。

注:yield就是当当前线程临时暂停让其他线程运行。
join方法表示run方法完成后台程序在继续执行。也就是合并子线程到主线程里,是程序顺序执行。
如:thread1.join(); // 等线程thread1结束后再继续执行
使用interrupt方法终止线程

使用interrupt方法来终端线程可分为两种情况:
(1)线程处于阻塞状态,如使用了sleep方法。
(2)使用while(!isInterrupted()){...}来判断线程是否被中断。
在第一种情况下使用interrupt方法,sleep方法将抛出一个InterruptedException例外,而在第二种情况下线程将直接退出。
在Thread类中有两个方法可以判断线程是否通过interrupt方法被终止。一个是静态的方法interrupted(),一个是非静态的方法isInterrupted(),这两个方法的区别是interrupted用来判断当前线是否被中断,而isInterrupted可以用来判断其他线程是否被中断

线程声明周期总结:
当一个线程类被new出来以后就进入了初始化状态,当调用线程的start的方法以后就进入可运行状态,可运行状态表示该线程已经具备了运行条件就等待分配cpu的时间片就可以运行了。当获取到时间片以后就进入了运行状态。
情况一:进入运行状态后,执行完main方法等就进入终结状态。
情况二:进入运行状态后,调用Thread的sleep方法或是join方法,就进入阻塞状态当,当睡眠时间过了后就进入可运行状态,等待获取时间片接着运行。
情况三:进入运行状态以后,调用yield方法后会放弃时间片,进入可运行状态,再次获取时间片后才接这运行。
情况四:当进入运行状态后,当要调用的资源已经被其他线程占用,即不能拿到对象锁,就会进入锁池,先进先拿,等拿到对象锁后会进入可运行状态,活取到时间片后接着运行。
情况5:当进入运行状态后,当调用对象的wait方法后,会进入等待队列,当调用notify方法或是notifyAll方法后进入锁池。拿取到对象锁后,再进入可运行状态


线程one经过了500ms的sleep后,在某一时刻再次获得时间片,它将接着上一次的断点运行

死锁实例
1.public class DeadLockOneRunnable implements Runnable {
2. private byte [] bytes;
3. public DeadLockOneRunnable (byte [] bytes) {
4. this.bytes= bytes;
5. }
6. @Override
7. public void run() {
8. synchronized (bytes) {
9. while(true) {
10. System.out.println(Thread.currentThread().getName() + "is running...");
11. }
12. }
13. }
14.
15. public static void main(String[] args) {
16. byte [] bytes = new byte[0];
17. DeadLockOneRunnable run = new DeadLockOneRunnable(bytes);
18. Thread thread = new Thread(run, "thread");
19. thread.start();
20. synchronized (bytes) {
21. try {
22. thread.join();
23. } catch (InterruptedException e) {
24. e.printStackTrace();
25. }
26. }
27. System.out.println("main thread run over .");
28. }
29.}
public class DeadLockOneRunnable implements Runnable {
private byte [] bytes;
public DeadLockOneRunnable (byte [] bytes) {
this.bytes= bytes;
}
@Override
public void run() {
synchronized (bytes) {
while(true) {
System.out.println(Thread.currentThread().getName() + "is running...");
}
}
}

public static void main(String[] args) {
byte [] bytes = new byte[0];
DeadLockOneRunnable run = new DeadLockOneRunnable(bytes);
Thread thread = new Thread(run, "thread");
thread.start();
synchronized (bytes) {
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("main thread run over .");
}
} 说明:在main线程中获得了对象bytes的lock,然后线程thread通过join()方法,则主线程main必须要等到thread线程终止后才可以继续往下运行。但是,当线程thread运行后,发现在其run()方法内部synchronized(bytes),那么线程thread也需要持有对象bytes的lock才可以运行。此时的情况为main线程持有对象bytes的lock等待线程thread运行终止后运行,而线程thread又需要对象bytes的lock被释放;两个线程相互等待彼此的资源,产生死锁。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值