Object中的wait,notify,notifyAll基本使用
2018-03-21 20:27
441 查看
Obj.wait(),与Obj.notify()必须要与synchronized(Obj)一起使用,也就是wait,与notify是针对已经获取了Obj锁进行操作,从语法角度来说就是Obj.wait(),Obj.notify必须在synchronized(Obj){…}语句块内。从功能上来说wait就是说线程在获取对象锁后,主动释放对象锁,同时本线程休眠。直到有其它线程调用对象的notify()唤醒该线程,才能继续获取对象锁,并继续执行。相应的notify()就是对对象锁的唤醒操作。但有一点需要注意的是notify()调用后,并不是马上就释放对象锁的,而是在相应的synchronized(){}语句块执行结束,自动释放锁后,JVM会在wait()对象锁的线程中随机选取一线程,赋予其对象锁,唤醒线程,继续执行。这样就提供了在线程间同步、唤醒的操作。Thread.sleep()与Object.wait()二者都可以暂停当前线程,释放CPU控制权,主要的区别在于Object.wait()在释放CPU同时,释放了对象锁的控制。object.wait()方法:让拥有object对象的锁的线程进入等待状态,并释放对象锁。object.wait()和object.notify()和object.notifyall()必须写在synchronized方法内部或者synchronized块内部,因为: 这几个方法要求当前正在运行object.wait()方法的线程拥有object的对象锁。(1)wait() 方法用来控制当前线程停止执行,等待其他线程对此Object实例调用notify或者notifyAll方法之后再继续执行
(2)wait(long timeout) 此方法的作用和wait()类似,但是增加了一个超时的设置,如果等待时间超过了timeout设定的毫秒数,那么当前线程会继续执行
(3)notify()方法从所有wait线程中选择一个线程,让它开始执行
(4)notifyAll()方法通知所有等待此对象的线程,开始执行1、假定我们有两个线程要打印1到9这9个数字,要求第一个线程打印1,2,3然后停止打印,由线程2打印4,5,6,然后线程2停止打印,通知线程1继续打印7,8,9.
(2)wait(long timeout) 此方法的作用和wait()类似,但是增加了一个超时的设置,如果等待时间超过了timeout设定的毫秒数,那么当前线程会继续执行
(3)notify()方法从所有wait线程中选择一个线程,让它开始执行
(4)notifyAll()方法通知所有等待此对象的线程,开始执行1、假定我们有两个线程要打印1到9这9个数字,要求第一个线程打印1,2,3然后停止打印,由线程2打印4,5,6,然后线程2停止打印,通知线程1继续打印7,8,9.
public class Example { public static void main(String[] args) { Object printACon = new Object(); Object printBCon = new Object(); new Thread(new PrintA(printACon, printBCon)).start(); new Thread(new PrintB(printACon, printBCon)).start(); } } class PrintA implements Runnable { private Object objectA = null; private Object objectB = null; PrintA(Object printACon, Object printBCon) { objectA = printACon; objectB = printBCon; } @Override public void run() { System.out.println("PrintA start......"); for (int i = 1; i < 4; i++) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("printA print " + i); } try { // A线程打印完了1、2、3后通知线程开始打印并且自身开始等待 synchronized(objectA) { synchronized(objectB) { objectB.notify(); } objectA.wait(); } } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("PrintA reStart......"); for (int i = 7; i < 10; i++) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("printA print " + i); } } } class PrintB implements Runnable { private Object objectA = null; private Object objectB = null; PrintB(Object printACon, Object printBCon) { objectA = printACon; objectB = printBCon; } @Override public void run() { try { // 刚开始B线程等待A线程打印完1、2、3 synchronized(objectB) { objectB.wait(); } } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("PrintB start......"); for (int i = 4; i < 7; i++) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("printB print " + i); } // B线程打印完了4、5、6后就通知A线程继续打印 synchronized(objectA) { objectA.notify(); } } }2、生产者-消费者问题
class Producer implements Runnable { private final List<Integer> taskQueue; private final int MAX_CAPACITY; public Producer(List<Integer> sharedQueue, int size) { this.taskQueue = sharedQueue; this.MAX_CAPACITY = size; } @Override public void run() { int counter = 0; while (true) { try { produce(counter++); } catch (InterruptedException ex) { ex.printStackTrace(); } } } private void produce(int i) throws InterruptedException { synchronized (taskQueue) { while (taskQueue.size() == MAX_CAPACITY) { System.out.println("Queue is full " + Thread.currentThread().getName() + " is waiting , size: " + taskQueue.size()); taskQueue.wait(); } Thread.sleep(1000); taskQueue.add(i); System.out.println("Produced: " + i); taskQueue.notifyAll(); } } }
class Consumer implements Runnable { private final List<Integer> taskQueue; public Consumer(List<Integer> sharedQueue) { this.taskQueue = sharedQueue; } @Override public void run() { while (true) { try { consume(); } catch (InterruptedException ex) { ex.printStackTrace(); } } } private void consume() throws InterruptedException { synchronized (taskQueue) { while (taskQueue.isEmpty()) { System.out.println("Queue is empty " + Thread.currentThread().getName() + " is waiting , size: " + taskQueue.size()); taskQueue.wait(); } Thread.sleep(1000); int i = (Integer) taskQueue.remove(0); System.out.println("Consumed: " + i); taskQueue.notifyAll(); } } }
public class ProducerConsumerExampleWithWaitAndNotify { public static void main(String[] args) { List<Integer> taskQueue = new ArrayList<Integer>(); int MAX_CAPACITY = 5; Thread tProducer = new Thread(new Producer(taskQueue, MAX_CAPACITY), "Producer"); Thread tConsumer = new Thread(new Consumer(taskQueue), "Consumer"); tProducer.start(); tConsumer.start(); } } Output: Produced: 0 Consumed: 0 Queue is empty Consumer is waiting , size: 0 Produced: 1 Produced: 2 Consumed: 1 Consumed: 2 Queue is empty Consumer is waiting , size: 0 Produced: 3 Produced: 4 Consumed: 3 Produced: 5 Consumed: 4 Produced: 6 Consumed: 5 Consumed: 6 Queue is empty Consumer is waiting , size: 0 Produced: 7 Consumed: 7 Queue is empty Consumer is waiting , size: 0原文地址:http://blog.csdn.net/hp910315/article/details/50148683
相关文章推荐
- Object中的wait,notify,notifyAll基本使用
- Object中的wait,notify,notifyAll基本使用(转)
- 【Java并发系列02】Object的wait()、notify()、notifyAll()方法使用
- Java并发07:Thread的基本方法(4)-Thread.sleep()、Object.wait()、notify()和notifyAll()
- Java中的synchronized、Object.wait()、Object.notify()/notifyAll()的使用
- java线程同步:使用Object的wait,notify,notifyAll做线程调度
- Java中级----多线程同步基本思想,java多线程设计wait、notify、notifyall、synchronized的使用机制(转)
- JAVA源码剖析之---Object类(三)---toString,wait,notify,notifyAll,finalize方法的使用
- 【Java基础之Object类(二)、线程同步(一)】Java中使用Object类的wait,notify,notifyAll做线程调度
- java线程同步:使用Object的wait,notify,notifyAll做线程调度
- 使用Object的wait,notify,notifyAll做线程调度
- java中wait,notify,notifyAll的使用方法
- 最简实例说明wait、notify、notifyAll的使用方法
- 最简实例说明wait、notify、notifyAll的使用方法
- [JAVA] java多线程设计wait、notify、notifyall、synchronized的使用机制
- Java中的Object的Wait() 和notify()方法使用时应注意的地方和Thread中的sleep()方法
- 最简实例说明wait、notify、notifyAll的使用方法
- Thread_wait、notify、notifyAll的使用方法
- 最简实例说明wait、notify、notifyAll的使用方法
- android-多线程设计wait、notify、notifyall、synchronized的使用机制