首先谈下wait(),notify(),notifyAll(),这个三个方法都是Object里的方法,具体详细作用可以查看API文档:
wait():
/**
* Causes the current thread to wait until another thread invokes the
* {@link java.lang.Object#notify()} method or the
* {@link java.lang.Object#notifyAll()} method for this object, or
* some other thread interrupts the current thread, or a certain
* amount of real time has elapsed.
* <p>
notify():
/**
* Wakes up a single thread that is waiting on this object's
* monitor. If any threads are waiting on this object, one of them
* is chosen to be awakened. The choice is arbitrary and occurs at
* the discretion of the implementation. A thread waits on an object's
* monitor by calling one of the {@code wait} methods.
* <p>
且这三个方法都是native方法。简单的说明这三个方法作用:
如果对象调用了wait方法就会使持有该对象的线程把该对象的控制权交出去,然后处于等待状态。
如果对象调用了notify方法就会通知某个正在等待这个对象的控制权的线程可以继续运行。
如果对象调用了notifyAll方法就会通知所有等待这个对象控制权的线程继续运行。
关于synchronize与volatile参考之前的文章http://blog.csdn.net/bat_os/article/details/53040490
简单分析下生产者与消费者之间的关系,比如厨师就是生产者,顾客是消费者,服务员按照厨师做好菜的顺序把菜送达。下面用wait,notify解决该问题:
public class Task implements Runnable {
private volatile static int i = 0;
public void run() {
System.out.println("任务" + ++i + "执行完");
}
}
/**
* Created by diy_os on 2016/11/6.
*/
public class ThreadPool {
private static int workThreadNum = 3;
private volatile static int FINISH_TASK = 0;
private WorkerThread workerThread[];
private List<Runnable> listqueue = new LinkedList<Runnable>();
private static ThreadPool threadPool;
public ThreadPool(){
this(workThreadNum);//无参构造器
}
public ThreadPool(int workNum){
ThreadPool.workThreadNum = workNum;
workerThread = new WorkerThread[workThreadNum];
for(int i=0;i<workThreadNum;i++) {
workerThread[i] = new WorkerThread();
workerThread[i].start();
}
}
public static ThreadPool getThreadPool(){
return new ThreadPool(workThreadNum);
}
public static ThreadPool getThreadPool(int workThreadNum){
if(threadPool == null){
return new ThreadPool(workThreadNum);
}
return threadPool;
}
public void execute(Runnable runnable){
synchronized (listqueue){
listqueue.add(runnable);
listqueue.notify();
}
}
public void execute(Runnable runnable[]){
synchronized (listqueue) {
for (Runnable c : runnable) {
listqueue.add(c);
listqueue.notify();
}
}
}
public void execute(List<Runnable> runnables){
synchronized (listqueue){
for(int i = 0;i<runnables.size();i++) {
listqueue.add(runnables.get(i));
}
}
}
public class WorkerThread extends Thread{
boolean isRunning = true;
Runnable runnable;
public void run(){
while (isRunning){
synchronized (listqueue) {
if (isRunning && listqueue.isEmpty()) {
try {
listqueue.wait(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (!listqueue.isEmpty()) {
runnable = listqueue.remove(0);
}
}
if (runnable != null) {
runnable.run();
}
FINISH_TASK++;
runnable = null;
}
}
}
}
public class Test {
public static void main(String[] args){
ThreadPool threadPool = ThreadPool.getThreadPool(5);
threadPool.execute(new Runnable[]{new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task()});
threadPool.execute(new Runnable[]{new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task()});
threadPool.execute(new Runnable[]{new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task(),new Task()});
}
}