可以利用阻塞队列使用生产者——消费者模式,生产者把数据放入队列,而消费者从队列中读取数据,生产者不需要知道消费者的状态和数量,消费者同样不需要知道生产者是谁,只是从队列中读取数据进行使用。
package com.pingan.home.demo; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingDeque; public class BlockQueueShow { static BlockingQueue<Integer> blockingQueue = new LinkedBlockingDeque<Integer>();; public static void main(String[] args) { Thread product = new Thread(new BlockQueueCreate()); Thread consumer = new Thread(new BlockQueueConsumer()); product.start(); consumer.start(); } } class BlockQueueCreate implements Runnable { @Override public void run() { try { for (int i = 0; i < 10; i++) { BlockQueueShow.blockingQueue.put(i); Thread.sleep(1000); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } class BlockQueueConsumer implements Runnable { @Override public void run() { try { while (true) { System.out.println("Take:"+BlockQueueShow.blockingQueue.take()); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } }
package com.pingan.home.demo; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class CountDownLatchShow { /* 模拟了100米赛跑,10名选手已经准备就绪,只等裁判一声令下。当所有人都到达终点时,比赛结束。 */ public static void main(String[] args) throws InterruptedException { ExecutorService runners = Executors.newFixedThreadPool(10); /* 十名选手 */ for (int i = 0; i < 10; i++) { Runner runner=new Runner(); runners.submit(runner); } /* begin减一,开始游戏 */ CountDownLatchUtil.begin.countDown(); long beginTime = System.nanoTime(); /* 等待end变为0,即所有选手到达终点 */ CountDownLatchUtil.end.await(); long lastEndTime = System.nanoTime(); System.out.println(lastEndTime - beginTime); runners.shutdown(); } } class CountDownLatchUtil{ /* 开始的倒数锁 */ final static CountDownLatch begin = new CountDownLatch(1); /* 结束的倒数锁 */ final static CountDownLatch end = new CountDownLatch(10); } class Runner implements Runnable { @Override public void run() { try { System.out.println(Thread.currentThread().getName()+ ":准备好"); long everyoneStartTime = System.nanoTime(); /** * 1.如果当前计数为零,则此方法立即返回,顺序执行下面代码。 * 2.等待(begin.countDown()代码后才会释放所有等待线程) */ CountDownLatchUtil.begin.await(); Thread.sleep((long) (Math.random() * 1000)); long everyoneEndTime = System.nanoTime(); System.out.println(Thread.currentThread().getName()+ ":跑完"+ (everyoneEndTime - everyoneStartTime)); } catch (InterruptedException e) { e.printStackTrace(); } finally { /* 每个选手到达终点时,end就减一 */ CountDownLatchUtil.end.countDown(); } } }
package com.pingan.home.demo; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; public class SemaphoreShow { public static void main(String[] args) { // 线程池 ExecutorService exec = Executors.newCachedThreadPool(); // 只能5个线程同时访问 final Semaphore semp = new Semaphore(5); // 模拟20个客户端访问 for (int index = 0; index < 20; index++) { final int NO = index; Runnable run = new Runnable() { public void run() { try { // 获取许可 semp.acquire(); System.out.println("Accessing: " + NO); Thread.sleep((long) (Math.random() * 10000)); // 访问完后,释放 ,如果屏蔽下面的语句,则在控制台只能打印5条记录,之后线程一直阻塞 semp.release(); } catch (InterruptedException e) { } } }; exec.execute(run); } // 退出线程池 exec.shutdown(); } }