《Java Concurrency in Practice》ch5 Building Blocks

《Java并行编程实战》ch5 基础构建模块 这章写的真不错,总结了3个有意思的问题。


1. 不使用信号量,实现生产者-消费者问题

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class PC {

	public static void main(String[] args) {
		BlockingQueue<Integer> q = new LinkedBlockingQueue<Integer>(3);
		Producer p = new Producer(q);
		Consumer c1 = new Consumer(q);
		Consumer c2 = new Consumer(q);
		new Thread(p).start();
		new Thread(c1).start();
		new Thread(c2).start();
	}

}

class Producer implements Runnable {
	private final BlockingQueue<Integer> queue;

	public Producer(BlockingQueue<Integer> q) {
		queue = q;
	}

	public void run() {
		try {
			while (true) {
				System.out.println("size : " + queue.size());
				System.out.println(">> put ");
				queue.put(produce());
				System.out.println("<< put ");
			}
		} catch (InterruptedException ex) {
			ex.printStackTrace();
		}
	}

	Integer produce() {
		int a = (int) (Math.random() * 1000);
		System.out.println("Producer produced " + a);
		
//		try {
//			Thread.sleep(100);
//		} catch (InterruptedException e) {
//			e.printStackTrace();
//		}
		return a;
	}
}

class Consumer implements Runnable {
	private final BlockingQueue<Integer> queue;

	public Consumer(BlockingQueue<Integer> q) {
		queue = q;
	}

	public void run() {
		try {
			while (true) {
				consume(queue.take());
			}
		} catch (InterruptedException ex) {
			ex.printStackTrace();
		}
	}

	void consume(Integer x) {
		try {
			System.out.println("Consumer " + Thread.currentThread().getId()
					+ " is consuming " + x.intValue());
			Thread.sleep(x.intValue());
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

运行结果:
size : 0
>> put 
Producer produced 396
Consumer 10 is consuming 396
<< put 
size : 0
>> put 
Producer produced 236
<< put 
size : 1
>> put 
Producer produced 899
<< put 
size : 2
>> put 
Producer produced 555
<< put 
size : 3
>> put 
Producer produced 601
<< put 
size : 3
>> put 
Producer produced 609
Consumer 9 is consuming 236
Consumer 9 is consuming 899
<< put 
size : 3
>> put 
Producer produced 561
Consumer 10 is consuming 555
<< put 
size : 3
>> put 
Producer produced 377
Consumer 10 is consuming 601
<< put 
size : 3
>> put 
Producer produced 872
Consumer 9 is consuming 609
<< put 
size : 3
>> put 
Producer produced 818
Consumer 10 is consuming 561
<< put 
size : 3
>> put 
Producer produced 872
Consumer 9 is consuming 377
<< put 
size : 3
>> put 
Producer produced 522
<< put 
size : 3
>> put 
Producer produced 841
Consumer 10 is consuming 872
Consumer 9 is consuming 818
<< put 
size : 3
>> put 
Producer produced 540
Consumer 9 is consuming 872
<< put 
size : 3
>> put 
Producer produced 90
Consumer 10 is consuming 522
<< put 
size : 3
>> put 
Producer produced 576

从上面的结果可以看出,当BlockingQueue满了后,生产者在执行put时会被阻塞住,当消费者从队列里取走一个元素后,生产者的put才会成功返回。


2. 如何让一组线程同时开始?如何等待一组线程全部结束?

CountDownLatch!


3. 如何实现高效的缓存服务器?

ConcurrentHashMap + FutureTask


你可能感兴趣的:(《Java Concurrency in Practice》ch5 Building Blocks)