死锁线程bing
Posted 鸟随二月
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了死锁线程bing相关的知识,希望对你有一定的参考价值。
前言
定义:在两个或者两个以上的线程运行中,因为资源抢占而造成线程一直等待的问题。
检测工具:jconsole、jmc、jvisualvm
位置:
JDK8\\bin
造成死锁的4个条件:
死锁代码:
1.互斥条件:当资源被一个线程拥有之后,就不能被其它的线程拥有了。(不可更改)
⒉.请求拥有条件:当一个线程拥有了一个资源之后又试图请求另一个资源。(可以解决)
3.不可剥夺条件:当一个资源被一个线程拥有之后,如果不是这个线程主动释放此资源的情况下,其他线程不能拥有此资源。(不可更改)
4.环路等待条件:两个或两个以上的线程在拥有了资源之后,试图获取对方资源的时候形成了一个环路。(可以解决)
解决
解决造成死锁的4个条件中的请求拥有条件或者环路等待条件。
死锁解决的问题最有效的解决方案:控制加锁的顺序。解决环路等待条件。
线程通讯
wait【休眠线程】/notify【唤醒一个线程】/notifyAll【唤醒全部线程】
所谓的线程通讯指的是在一个线程中的操作可以影响另一个线程。
wait 注意事项:
1.wait方法在执行之前必须先加锁,也就是说 wait方法一定要配合 synchronized一起使用。
2.wait和notify 在配合synchronized 使用时,一定要注意要使用同一把锁。
3.wait 和 notify在配合使用时,一定要操作同一把锁。
错误的例子:
wait和notify / notfiyAll 的问题:
不能指定唤醒的线程。
wait在不传递任何参数的情况下会进入waiting状态,当wait里面时候这了一个大于0的整数时,它会进入limed_waiting。
wait和sleep区别
相同点:
1.wait和 sleep都是让线程进行休眠状态。
2.wait和 sleep在执行的过程中都可以接收到终止线程执行的通知。
不同点:
1.wait使用必须配合synchronized一起使用,而sleep不用。
2.wait会释放锁,而sleep不会释放锁。
3.wait是0bject 的方法,而sleep是Thread(线程)的方法。
4.默认情况下 wait(不传递任何参数或者是参数为0的情况下)它会进入 waiting 状态,而sleep会进入timed waiting状态。
5.使用 wait 时可以主动的唤醒线程,而使用sleep 时不能主动唤醒线程。
sleep(0) vs wait(0)区别
1.sleep(0)表示过0毫秒之后继续执行,而wait(0)表示一直休眠。2.sleep(0)表示重新触发一次CPU竞争。
为什么wait会释放锁, 而sleep不会释放锁
答: sleep必须要传递一个最大等待时间的,也说 sleep是可控的(对于时间层面来讲),而 wait 是可以不传递传输,从设计层面来讲如果让 wait这个没有超时等待时间的机制不释放锁的话,那么线程可能会一直阻塞,而sleep 就不存在这个问题。
为什么wait 是0bject的方法,而sleep是Thread 的方法
答: wait需要操作锁,而锁是属于对象级别(所有的锁都是放在对象头当中),它不是线程级别,一个线程中可以有多把锁,为了灵活起见,所以就将 wait放在0bject 当中。
解决wait/notify 随机唤醒的问题—— LockSupport park ()/unpark(线程)
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
// 让线程进行休眠
LockSupport.park();
System.out.println("唤醒 t1");
}
}, "t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
// 让线程进行休眠
LockSupport.park();
System.out.println("唤醒 t2");
}
}, "t2");
Thread t3 = new Thread(new Runnable() {
@Override
public void run() {
// 让线程进行休眠
LockSupport.park();
System.out.println("唤醒 t3");
}
}, "t3");
t1.start();
t2.start();
t3.start();
LockSupport.unpark(t2);
}
LockSupport 虽然不会报Interrupt 的异常,但依旧可以监听到线程中止的指令。
测试例子:
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("park 之前 Interrupt 状态:" +
Thread.currentThread().isInterrupted());
// 线程进入休眠
LockSupport.park();
System.out.println("park 之后 Interrupt 状态:" +
Thread.currentThread().isInterrupted());
}
}, "t1");
// 启动线程
t1.start();
Thread.sleep(100);
// 中止线程
t1.interrupt();
// 唤醒线程 t1
LockSupport.unpark(t1);
}
以上是关于死锁线程bing的主要内容,如果未能解决你的问题,请参考以下文章