死锁问题
不同线程,分别占用对方的同步资源不放弃,都等对方放弃,就会形成死锁
形成死锁之后,不会出现异常,不会出现提示,只是所有线程都处于阻塞状态,无法继续。
Lock
是同步代码方法之外的一种,解决线程安全问题的方法
synchronized和lock的异同
都用于解决线程安全问题
不同点在于:
synchronized在执行完代码后,自动释放监视器。
lock手动启动同步,手动释放同步unlock()。
推荐优先使用lock。
三种方法对比
- wait() 一旦进入此方法,当前线程就进入阻塞状态,并释放同步监视器
- notify() 一旦执行,就会唤醒被wait的一个线程,如果多个线程wait就唤醒优先级最高的
- notifyall() 所有的wait线程都唤醒
面试题
sleep()和wait()
一旦执行这两种方法,都可以使当前线程进入阻塞态。
(1)但是两个方法使用的位置不同。
Thread类中声明sleep(),object中声明wait()
(2)调用的范围或者要求不同
sleep()需要的时候就可以调用
wait()一定要放在同步代码块中
(3)是否释放同步监视器的问题
sleep()不会释放
wait()会
class Number implements Runnable{
private int num =1;
@Override
public void run() {
while(true){
synchronized (this) {
this.notify();
//唤醒线程
if(num<=100){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+":"+num);
num++;
try {
//使得调用该方法的线程进入阻塞
//使用wait 会释放线程锁
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
break;
}
}
}
}
}
public class ThreadCommunication {
public static void main(String[] args) {
Number num1=new Number();
Thread t1=new Thread(num1);
Thread t2=new Thread(num1);
Thread t3=new Thread(num1);
t1.setName("Thread1");
t2.setName("Thread2");
t1.start();
t2.start();
}
}