二、方法await()/signal()
在JDK5.0以后,JAVA提供了新的更加健壮的线程处理机制,包括了同步、锁定、线程池等等,可以实现更小粒度上的控制。await()和signal()就是其中用来同步的两种方法,功能基本上和wait()/notify()相同,完全可以取代它们,但是它们和新引入的锁定机制Lock直接挂钩,具有更大的灵活性。
import java.util.LinkedList; import java.util.concurrent.locks.*; public class Sycn2 { private LinkedList<Object> myList = new LinkedList<Object>(); private int MAX = 10; private final Lock lock = new ReentrantLock(); private final Condition full = lock.newCondition(); private final Condition empty = lock.newCondition(); public void start() { new Thread(new Producer()).start(); new Thread(new Consumer()).start(); } public static void main(String[] args) throws Exception { Sycn2 s2 = new Sycn2(); s2.start(); } class Producer implements Runnable { public void run() { while (true) { lock.lock(); try { while (myList.size() == MAX) { System.out.println("warning: it's full!"); full.await(); } Object o = new Object(); if (myList.add(o)) { System.out.println("Producer: " + o); empty.signal(); } } catch (InterruptedException ie) { System.out.println("producer is interrupted!"); } finally { lock.unlock(); } } } } class Consumer implements Runnable { public void run() { while (true) { lock.lock(); try { while (myList.size() == 0) { System.out.println("warning: it's empty!"); empty.await(); } Object o = myList.removeLast(); System.out.println("Consumer: " + o); full.signal(); } catch (InterruptedException ie) { System.out.println("consumer is interrupted!"); } finally { lock.unlock(); } } } } } |
三、阻塞队列方法BlockingQueue
BlockingQueue也是JDK5.0的一部分,是一个已经在内部实现了同步的队列,实现方式采用的是第2种await()/signal()方法。它可以在生成对象时指定容量大小。它用于阻塞操作的是put()和take()方法。
put()方法类似于上面的生产者线程,容量最大时自动阻塞。
take()方法类似于上面的消费者线程,容量为0时自动阻塞。
import java.util.concurrent.*; public class Sycn3 { private LinkedBlockingQueue<Object> queue = new LinkedBlockingQueue<Object>(10); private int MAX = 10; public void start() { new Thread(new Producer()).start(); new Thread(new Consumer()).start(); } public static void main(String[] args) throws Exception { Sycn3 s3 = new Sycn3(); s3.start(); } class Producer implements Runnable { public void run() { while (true) { try { if (queue.size() == MAX) System.out.println("warning: it's full!"); Object o = new Object(); queue.put(o); System.out.println("Producer: " + o); } catch (InterruptedException e) { System.out.println("producer is interrupted!"); } } } } class Consumer implements Runnable { public void run() { while (true) { try { if (queue.size() == 0) System.out.println("warning: it's empty!"); Object o = queue.take(); System.out.println("Consumer: " + o); } catch (InterruptedException e) { System.out.println("producer is interrupted!"); } } } } } |