在Java中一共有四种方法支持同步,其中前三个是同步方法,一个是管道方法。
(1)wait() / notify()方法
(2)await() / signal()方法
(3)BlockingQueue阻塞队列方法
(4)PipedInputStream / PipedOutputStream
本人编写的JAVA代码只实现了最常用的前三种。JAVA代码在 eclipse 调试通过。
有一篇文章也不错,可以去看看
http://blog.csdn.net/monkey_d_meng/article/details/6251879
代码如下:
package threadSync;
import java.util.LinkedList; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;
/** * 仓库类Storage的父类,做接口用,其子类必须重载这两个方法 * */ class SupperStorage { public void produce(int num){ System.out.println("SupperStorage::produce()"); }; public void consume(int num){ System.out.println("SupperStorage::consume()"); }; }
/** * 仓库类Storage3实现缓冲区 with LinkedBlockingQueue * */ class Storage3 extends SupperStorage { // 仓库最大存储量 private final int MAX_SIZE = 200; // 仓库存储的载体 private LinkedBlockingQueue<Object>list=new LinkedBlockingQueue<Object>(MAX_SIZE);
// 生产num个产品 public void produce(int num) { // 如果仓库 is full if (list.size() == MAX_SIZE) { System.out.println("【库存量】 is full: " + MAX_SIZE + " 暂时不能执行生产任务!"); }
// 生产条件满足情况下,生产num个产品 for (int i = 1; i <= num; ++i) { try { // 放入产品,自动阻塞 list.put(new Object()); } catch (InterruptedException e) { e.printStackTrace(); }
System.out.println("【现仓储量为】: " + list.size()); } }
// 消费num个产品 public void consume(int num) { // 如果仓库存储量不足 if (list.size() == 0) { System.out.println("【库存量】 is empty, 暂时不能执行消费任务!"); }
// 消费条件满足情况下,消费num个产品 for (int i = 1; i <= num; ++i) { try { // 消费产品,自动阻塞 list.take(); } catch (InterruptedException e) { e.printStackTrace(); } }
System.out.println("【现仓储量为】: " + list.size()); }
// set/get方法 public LinkedBlockingQueue<Object> getList() { return list; }
public void setList(LinkedBlockingQueue<Object> list) { this.list = list; }
public int getMAX_SIZE() { return MAX_SIZE; } } /** * 仓库类Storage2实现缓冲区 with await() / signal() * */ class Storage2 extends SupperStorage { // 仓库最大存储量 private final int MAX_SIZE = 200; // 仓库存储的载体 private LinkedList<Object> list = new LinkedList<Object>(); // 锁 private final Lock lock = new ReentrantLock(); // 仓库满的条件变量 private final Condition full = lock.newCondition(); // 仓库空的条件变量 private final Condition empty = lock.newCondition();
// 生产num个产品 public void produce(int num) { // 获得锁 lock.lock();
// 如果仓库剩余容量不足 while (list.size() + num > MAX_SIZE) { System.out.println("【要生产的产品数量】: " + num + " 【库存量】:" + list.size() + " 暂时不能执行生产任务!"); try { // 由于条件不满足,生产阻塞 System.out.println(Thread.currentThread().getName()+" enter await"); full.await(); } catch (InterruptedException e) { e.printStackTrace(); } }
// 生产条件满足情况下,生产num个产品 for (int i = 1; i <= num; ++i) { list.add(new Object()); }
System.out.println(Thread.currentThread().getName() + " 【已经生产产品数】:" + num + " 【现仓储量为】:" + list.size());
// 唤醒其他所有线程 full.signalAll(); empty.signalAll();
// 释放锁 lock.unlock(); }
// 消费num个产品 public void consume(int num) { // 获得锁 lock.lock();
// 如果仓库存储量不足 while (list.size() < num) { System.out.println( Thread.currentThread().getName() + "【要消费的产品数量】: " + num + " 【库存量】:" + list.size() + " 暂时不能执行消费任务!"); try { // 由于条件不满足,消费阻塞 System.out.println(Thread.currentThread().getName()+" enter await"); empty.await(); } catch (InterruptedException e) { e.printStackTrace(); } }
// 消费条件满足情况下,消费num个产品 for (int i = 1; i <= num; ++i) { list.remove(); }
System.out.println(Thread.currentThread().getName() + " 【已经消费产品数】: " + num + " 【现仓储量为】:" + list.size());
// 唤醒其他所有线程 full.signalAll(); empty.signalAll();
// 释放锁 lock.unlock(); }
// set/get方法 public int getMAX_SIZE() { return MAX_SIZE; }
public LinkedList<Object> getList() { return list; }
public void setList(LinkedList<Object> list) { this.list = list; } } // Storage with wait() / notify() class Storage extends SupperStorage { // 仓库最大存储量 private final int MAX_SIZE = 200;
// 仓库存储的载体 private LinkedList<Object> list = new LinkedList<Object>();
// 生产num个产品 public void produce(int num) { // 同步代码段 synchronized (list) { // 如果仓库剩余容量不足 while (list.size() + num > MAX_SIZE) { System.out.println("【要生产的产品数量】:" + num + "/t【库存量】:" + list.size() + "/t暂时不能执行生产任务!"); try { // 由于条件不满足,生产阻塞 list.wait(); } catch (InterruptedException e) { e.printStackTrace(); } }
// 生产条件满足情况下,生产num个产品 for (int i = 1; i <= num; ++i) { list.add(new Object()); }
System.out.println("【已经生产产品数】:" + num + "/t【现仓储量为】:" + list.size());
list.notifyAll(); } }
// 消费num个产品 public void consume(int num) { // 同步代码段 synchronized (list) { // 如果仓库存储量不足 while (list.size() < num) { System.out.println("【要消费的产品数量】:" + num + "/t【库存量】:" + list.size() + "/t暂时不能执行生产任务!"); try { // 由于条件不满足,消费阻塞 list.wait(); } catch (InterruptedException e) { e.printStackTrace(); } }
// 消费条件满足情况下,消费num个产品 for (int i = 1; i <= num; ++i) { list.remove(); }
System.out.println("【已经消费产品数】:" + num + "/t【现仓储量为】:" + list.size());
list.notifyAll(); } }
// get/set方法 public LinkedList<Object> getList() { return list; }
public void setList(LinkedList<Object> list) { this.list = list; }
public int getMAX_SIZE() { return MAX_SIZE; } } /* * 生产者类Producer继承线程类Thread * */ class Producer extends Thread { // 每次生产的产品数量 private int num; // 所在放置的仓库 private SupperStorage storage; // 构造函数,设置仓库 public Producer(SupperStorage storage) { this.storage = storage; } // 线程run函数 public void run() { produce(num); } // 调用仓库Storage的生产函数 public void produce(int num) { storage.produce(num); } // get/set方法 public int getNum() { return num; } public void setNum(int num) { this.num = num; } public SupperStorage getStorage() { return storage; } public void setStorage(SupperStorage storage) { this.storage = storage; } }
class Producer2 implements Runnable { // 每次生产的产品数量 private int num; // 所在放置的仓库 private SupperStorage storage; // 构造函数,设置仓库 public Producer2(SupperStorage storage) { this.storage = storage; } // 线程run函数 public void run() { produce(num); } // 调用仓库Storage的生产函数 public void produce(int num) { storage.produce(num); } // get/set方法 public int getNum() { return num; } public void setNum(int num) { this.num = num; } public SupperStorage getStorage() { return storage; } public void setStorage(SupperStorage storage) { this.storage = storage; } }
class Consumer extends Thread { // 每次消费的产品数量 private int num;
// 所在放置的仓库 private SupperStorage storage;
// 构造函数,设置仓库 public Consumer(SupperStorage storage) { this.storage = storage; }
// 线程run函数 public void run() { consume(num); }
// 调用仓库Storage的生产函数 public void consume(int num) { storage.consume(num); }
// get/set方法 public int getNum() { return num; }
public void setNum(int num) { this.num = num; }
public SupperStorage getStorage() { return storage; }
public void setStorage(SupperStorage storage) { this.storage = storage; } } class Consumer2 implements Runnable { // 每次消费的产品数量 private int num;
// 所在放置的仓库 private SupperStorage storage;
// 构造函数,设置仓库 public Consumer2 (SupperStorage storage) { this.storage = storage; }
// 线程run函数 public void run() { consume(num); }
// 调用仓库Storage的生产函数 public void consume(int num) { storage.consume(num); }
// get/set方法 public int getNum() { return num; }
public void setNum(int num) { this.num = num; }
public SupperStorage getStorage() { return storage; }
public void setStorage(SupperStorage storage) { this.storage = storage; } } /** * 测试类Test * */ public class mythreadsync { //this method is used to test thread generated via class Thread public void test_thread() { System.out.println("test_thread(): enter"); //SupperStorage storage = new Storage3(); //SupperStorage storage = new Storage(); SupperStorage storage = new Storage2(); // 生产者对象 Producer p1 = new Producer(storage); Producer p2 = new Producer(storage); Producer p3 = new Producer(storage); Producer p4 = new Producer(storage); Producer p5 = new Producer(storage); Producer p6 = new Producer(storage); Producer p7 = new Producer(storage);
// 消费者对象 Consumer c1 = new Consumer(storage); Consumer c2 = new Consumer(storage); Consumer c3 = new Consumer(storage);
// 设置生产者产品生产数量 p1.setNum(10); p2.setNum(10); p3.setNum(10); p4.setNum(10); p5.setNum(10); p6.setNum(10); p7.setNum(80);
// 设置消费者产品消费数量 c1.setNum(50); c2.setNum(20); c3.setNum(30);
// 线程开始执行 c1.start(); c2.start(); c3.start(); p1.start(); p2.start(); p3.start(); p4.start(); p5.start(); p6.start(); p7.start(); System.out.println("test_thread(): exit"); } //this method is used to test threads implementing interface runnable public void test_thread_runnable() { System.out.println("test_thread_runnable(): enter"); SupperStorage storage = new Storage2(); // 生产者对象 Producer2 p1 = new Producer2(storage); Producer2 p2 = new Producer2(storage); Producer2 p3 = new Producer2(storage); Producer2 p4 = new Producer2(storage); Producer2 p5 = new Producer2(storage); Producer2 p6 = new Producer2(storage); Producer2 p7 = new Producer2(storage);
// 消费者对象 Consumer2 c1 = new Consumer2(storage); Consumer2 c2 = new Consumer2(storage); Consumer2 c3 = new Consumer2(storage);
// 设置生产者产品生产数量 p1.setNum(10); p2.setNum(10); p3.setNum(10); p4.setNum(10); p5.setNum(10); p6.setNum(20); p7.setNum(80);
// 设置消费者产品消费数量 c1.setNum(50); c2.setNum(20); c3.setNum(30);
// 线程开始执行 new Thread(c1,"consumer 1").start(); new Thread(c2,"consumer 2").start(); new Thread(c3,"consumer 3").start(); new Thread(p1,"producer 1").start(); new Thread(p2,"producer 2").start(); new Thread(p3,"producer 3").start(); new Thread(p4,"producer 4").start(); new Thread(p5,"producer 5").start(); new Thread(p6,"producer 6").start(); new Thread(p7,"producer 7").start(); System.out.println("test_thread_runnable(): exit"); } //this method is used to test threads pool for thread implementing interface runnable public void test_threadpool_runnal() { System.out.println("test_threadpool_runnal(): enter"); SupperStorage storage = new Storage2(); // 生产者对象 Producer2 p1 = new Producer2(storage); Producer2 p2 = new Producer2(storage); Producer2 p3 = new Producer2(storage); Producer2 p4 = new Producer2(storage); Producer2 p5 = new Producer2(storage); Producer2 p6 = new Producer2(storage); Producer2 p7 = new Producer2(storage);
// 消费者对象 Consumer2 c1 = new Consumer2(storage); Consumer2 c2 = new Consumer2(storage); Consumer2 c3 = new Consumer2(storage);
// 设置生产者产品生产数量 p1.setNum(10); p2.setNum(20); p3.setNum(30); p4.setNum(40); p5.setNum(50); p6.setNum(60); p7.setNum(70);
// 设置消费者产品消费数量 c1.setNum(30); c2.setNum(50); c3.setNum(80); ExecutorService pool=Executors.newFixedThreadPool(5);//创建一个固定大小为5的线程池
// 线程开始执行 // 3 consumers pool.submit(c1); pool.submit(c2); pool.submit(c3); // 7 producers pool.submit(p1); pool.submit(p2); pool.submit(p3); pool.submit(p4); pool.submit(p5); pool.submit(p6); pool.submit(p7); /* * it shows, at most, only 5 working threads in parallel even if 10 tasks submitted. * test_threadpool_runnal(): enter pool-1-thread-1【要消费的产品数量】: 30 【库存量】:0 暂时不能执行消费任务! pool-1-thread-1 enter await pool-1-thread-2【要消费的产品数量】: 50 【库存量】:0 暂时不能执行消费任务! pool-1-thread-2 enter await pool-1-thread-4 【已经生产产品数】:10 【现仓储量为】:10 test_threadpool_runnal(): exit pool-1-thread-5 【已经生产产品数】:20 【现仓储量为】:30 pool-1-thread-3【要消费的产品数量】: 80 【库存量】:30 暂时不能执行消费任务! pool-1-thread-3 enter await pool-1-thread-1 【已经消费产品数】: 30 【现仓储量为】:0 pool-1-thread-1 【已经生产产品数】:50 【现仓储量为】:50 pool-1-thread-1 【已经生产产品数】:60 【现仓储量为】:110 pool-1-thread-1 【已经生产产品数】:70 【现仓储量为】:180 pool-1-thread-2 【已经消费产品数】: 50 【现仓储量为】:130 pool-1-thread-4 【已经生产产品数】:30 【现仓储量为】:160 pool-1-thread-5 【已经生产产品数】:40 【现仓储量为】:200 pool-1-thread-3 【已经消费产品数】: 80 【现仓储量为】:120 */
pool.shutdown();
System.out.println("test_threadpool_runnal(): exit"); } public static void main(String[] args) { mythreadsync my = new mythreadsync(); //my.test_thread(); my.test_threadpool_runnal(); //my.test_thread_runnable(); } }