sleep()
是Thread类的特有方法,wait() 与 notify/notifyAll() 是Object类的方法,在执行两个方法时,要先获得锁,因此wait() 与 notify/notifyAll() 一般是在临界区内执行,就是在加了synchronized的代码中执行
当线程执行wait()时,会把当前的锁释放,然后让出CPU,进入等待状态。
当执行notify/notifyAll方法时不会立即释放锁,会唤醒一个处于等待该对象锁的线程,然后继续往下执行,直到执行完退出对象锁锁住的区域(synchronized修饰的代码块)后再释放锁。notify/notifyAll()执行后,并不立即释放锁,而是要等到执行完临界区中代码后,再释放。在实际编程中,我们应该尽量在线程调用notify/notifyAll()后,立即退出临界区。即不要在notify/notifyAll()后面再写一些耗时的代码。
Thread.sleep()
让线程从 【running】 -> 【阻塞态】 时间结束/interrupt -> 【runnable】Object.wait()
让线程从 【running】 -> 【等待队列】notify -> 【锁池】 -> 【runnable】
推荐的常用同步方法
(1)Object的wait() / notify()方法
(2)Lock和Condition的await() / signal()方法
(3)BlockingQueue阻塞队列方法(推荐)
wait() / notify()方法-同步代码块
@Override
public void run() {
while (true) {
synchronized (queue) {
while ((queue.size() == Max_Size)) {
System.out.println(getName() + " queue is full!!");
try {
queue.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
int i = new Random().nextInt(10);
System.out.println(getName() + " put " + i + " into queue!");
queue.add(i);
try {
Thread.sleep(new Random().nextInt(1000));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
queue.notify();
}
}
}
业务类内循环调度,需获取wait()/notify()对象的锁,方法上加锁不行,需要对Object.wait()的Object加锁。遇不满足条件则进入等待。
wait() / notify()方法-同步方法
public static class Store {
private final int MAX_SIZE = 10;
private int count;
public synchronized void add () throws Exception{
if (count < MAX_SIZE) {
count++;
System.out.println(Thread.currentThread().getName()+" put "+count);
this.notifyAll();
}else {
System.out.println(Thread.currentThread().getName()+" store is full!!");
this.wait();
}
}
public synchronized void remove () throws Exception{
if (count >0) {
count--;
System.out.println(Thread.currentThread().getName()+" remove "+count);
this.notifyAll();
}else {
System.out.println(Thread.currentThread().getName()+" store is empty!!");
this.wait();
}
}
}
/*
* @author wsg
* 仓库类,提供添加和删除接口
*/
public static class Productor extends Thread{
private Store store;
public Store getStore() {
return store;
}
public void setStore(Store store) {
this.store = store;
}
@Override
public void run() {
while(true){
try {
store.add();
Thread.sleep(100);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
该实现方式把同步业务放在了共享存储内,存储应该只有增删功能,不符合面向对象的思想。在函数上增加同步,在函数内使用this.wait(),函数上增加synchronized等于对该对象this加锁,然后使用this.wait(),与需要对Object.wait()的Object加锁不冲突。
具体实现可参考:https://blog.youkuaiyun.com/u010983881/article/details/78554671