notify和notifyall的区别
可以通过notify或者是notufyall对锁进行唤醒
package com.interview.javabasic.thread;
public class WaitSleepDemo {
public static void main(String[] args) {
final Object lock = new Object();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("thread A is waiting to get lock");
synchronized (lock) {
try {
System.out.println("thread A get lock");
Thread.sleep(20);
System.out.println("thread A do wait method");
lock.wait();
System.out.println("thread A is done");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("thread B is waiting to get lock");
synchronized (lock) {
try {
System.out.println("thread B get lock");
System.out.println("thread B do wait method");
Thread.sleep(10);
System.out.println("thread B is done");
//lock.notify();
lock.notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
}
两个概念
- 锁池EntryList
- 等待池WaitSet
锁池
假设线程A已经拥有了某个对象(不是类)的锁,而其他线程B、C想要调用这个对象的某个 synchronized 方法(或者块),由于B、C线程在进入对象的 synchronized 方法(或者块)之前必须先获得该对象锁的拥有权,而恰巧该对象的锁目前正被线程A所占用,此时B、C线程就会被阻塞,进入一个地方去等待锁的释放,这个地方便是该对象的锁池。
等待池
假设线程A调用了某个对象的wait()方法,线程A就会释放该对象的锁,同时线程A就进入到了该对象的等待池中,进入到等待池中的线程不会去竞争该对象的锁。
notofy和notifyAll的区别
- notifyAll 会让所有处于等待池的线程全部进入锁池去竞争获取锁的机会
- notify 只会随机选取一个处于等待池中的线程进入锁池去竞争获取锁的机会。
package com.interview.javabasic.thread;
public class NotificationDemo {
private volatile boolean go = false;
public static void main(String[] args) throws InterruptedException {
final NotificationDemo test = new NotificationDemo();
Runnable waitTask = new Runnable() {
@Override
public void run() {
try {
test.shouldGo();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "fi");
}
};
Runnable notifyTask = new Runnable() {
@Override
public void run() {
test.go();
System.out.println(Thread.currentThread().getName() + "fo");
}
};
Thread t1 = new Thread(waitTask, "WT1");
Thread t2 = new Thread(waitTask, "WT2");
Thread t3 = new Thread(waitTask, "WT3");
Thread t4 = new Thread(notifyTask, "NT4");
t1.start();
t2.start();
t3.start();
Thread.sleep(200);
t4.start();
}
private synchronized void shouldGo() throws InterruptedException {
while(go != true) {
System.out.println(Thread.currentThread()
+ "is going to wait on this object" );
wait();
System.out.println(Thread.currentThread() + "is woken up");
}
go = false;
}
private synchronized void go() {
while (go == false) {
System.out.println(Thread.currentThread()
+ "is going to notify all or one thread waiting on");
go = true;
notify();
//notifyAll();
}
}
}