wait()?notify()?notifyAll()?
wait() : It tells the calling thread to give up the lock and go to sleep until some other thread enters the same monitor and calls notify(). The wait() method releases the lock prior to waiting and reacquires the lock prior to returning from the wait() method. The wait() method is actually tightly integrated with the synchronization lock, using a feature not available directly from the synchronization mechanism. In other words, it is not possible for us to implement the wait() method purely in Java: it is a native method.
General syntax for calling wait() method is like this:
synchronized( lockObject )
{
while( ! condition )
{
lockObject.wait();
}
//take the action here;
}
notify() : It wakes up one single thread that called wait() on the same object. It should be noted that calling notify() does not actually give up a lock on a resource. It tells a waiting thread that that thread can wake up. However, the lock is not actually given up until the notifier’s synchronized block has completed. So, if a notifier calls notify() on a resource but the notifier still needs to perform 10 seconds of actions on the resource within its synchronized block, the thread that had been waiting will need to wait at least another additional 10 seconds for the notifier to release the lock on the object, even though notify() had been called.
General syntax for calling notify() method is like this:
synchronized(lockObject)
{
//establish_the_condition;
lockObject.notify();
//any additional code if needed
}
notifyAll() : It wakes up all the threads that called wait() on the same object. The highest priority thread will run first in most of the situation, though not guaranteed. Other things are same as notify() method above.
General syntax for calling notify() method is like this:
synchronized(lockObject)
{
establish_the_condition;
lockObject.notifyAll();
}
生产者消费者模式
package com.demo;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Created by leslie on 17/7/2.
*/
public class ThreadDemo {
//生产者 消费者问题
static class Producer implements Runnable{
private final List<Integer> taskQueue;
private final int MAX_CAPACITY;
public Producer(List<Integer> taskQueue, int MAX_CAPACITY) {
this.taskQueue = taskQueue;
this.MAX_CAPACITY = MAX_CAPACITY;
}
public void run() {
int count = 0;
while (true){
try {
produce(count++);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void produce(int i) throws InterruptedException {
synchronized (taskQueue){
while (taskQueue.size()==MAX_CAPACITY){
try {
System.out.println("queue is full "+Thread.currentThread().getName()+" is waiting,queuesize is "+taskQueue.size());
taskQueue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Thread.sleep(1000);
taskQueue.add(i);
System.out.println(Thread.currentThread().getName()+" Produce added "+i);
taskQueue.notifyAll();
}
}
}
static class Consumer implements Runnable{
private final List<Integer> taskQUeue;
public Consumer(List<Integer> taskQUeue) {
this.taskQUeue = taskQUeue;
}
public void run() {
while (true){
try {
consumer();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void consumer() throws InterruptedException {
synchronized (taskQUeue){
while (taskQUeue.isEmpty()){
try {
System.out.println("queue is full "+Thread.currentThread().getName()+" is waitting");
taskQUeue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Thread.sleep(1000);
int i = taskQUeue.remove(0);
System.out.println(Thread.currentThread().getName()+" Consumer "+i);
taskQUeue.notifyAll();
}
}
}
public static void main(String[] args) {
ExecutorService service = Executors.newFixedThreadPool(5);
List<Integer> taskQueue = new ArrayList<Integer>();
int MAX_CAPACITY = 5;
service.execute(new Thread(new Producer(taskQueue, MAX_CAPACITY), "Producer"));
service.execute(new Thread(new Consumer(taskQueue), "Consumer1"));
service.execute(new Thread(new Consumer(taskQueue), "Consumer2"));
service.shutdown();
}
}
问题来了,对于顺序打印的问题该如何解决
package com.demo;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Created by leslie on 17/7/2.
*/
public class SeqPrint {
static class Worker extends Thread{
private AtomicInteger count;
private String word;
private int order;
private int runCount;
Worker(AtomicInteger count, String word, int order, int runCount) {
this.count = count;
this.word = word;
this.order = order;
this.runCount = runCount;
}
@Override
public void run() {
while(true){
synchronized (count){
if(count.get()%runCount==order){
System.out.println(word);
count.getAndAdd(1);
count.notifyAll();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
try {
count.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
public static void main(String[] args) {
ExecutorService service = Executors.newFixedThreadPool(4);
AtomicInteger count = new AtomicInteger(0);
int runCOunt = 4;
service.execute(new Worker(count,"A",0,runCOunt));
service.execute(new Worker(count,"B",1,runCOunt));
service.execute(new Worker(count,"C",2,runCOunt));
service.execute(new Worker(count,"D",3,runCOunt));
service.shutdown();
}
}