ew ArrayList<>(); Map<String, Integer> map = new HashMap<>(); count(list, map); list = new ArrayList<>(); map = new ConcurrentHashMap<>(); count(list, map); } }
通过这个程序,可以非常直观地看到这两者的区别。至于原理,就不必强记了,因为你不可能记住,记住了也没鸟用。
ArrayBlockingQueue和LinkedBlockingQueue在之前的线程池ThreadPool中也提过,它们的共同点都是一边放一边拿,唯一的不同是一个是数量有限的,一个是数量无限的。
之前拿上菜的案例演示了ArrayBlockingQueue,现在同样的案例再用LinkedBlockingQueue来实现:
/** * LinkedBlockingQueue测试 * * @author 湘王 */
public class LinkedBlockingQueueTester { public static BlockingQueue<String> queue = new LinkedBlockingQueue<String>(5); // 一个往里放
class Producer implements Runnable { @Override public void run() { try { queue.offer("川菜"); System.out.println(Thread.currentThread().getName() + " 厨师做好 川菜"); } catch (Exception e) { e.printStackTrace(); } } } // 一个往外拿
class Consumer implements Runnable { @Override public void run() { try { String food = queue.poll(); System.out.println(Thread.currentThread().getName() + " 客人消费 " + food); } catch (Exception e) { e.printStackTrace(); } } } public static void main(String[] args) { // 和ArrayBlockingQueue不讲究顺序不同,LinkedBlockingQueue需要将生产的一方放在前面 // 厨师做好菜
for (int i = 0; i < 5; i++) { new Thread(new LinkedBlockingQueueTester().new Producer()).start(); } // 客人等着菜
for (int i = 0; i < 5; i++) { new Thread(new LinkedBlockingQueueTester().new Consumer()).start(); } } }
JUC中一些其他的类,例如ForkJoinPool,可以把任务分解成更小的任务,被分解出来任务会被继续分解成更小的任务,更形象地说法是“分形器”。而RecursiveTask是一种会返回结果的任务,它可以将自己分解成若干更小的任务,并将这些任务的执行结果合并到一个结果里。这两种用的不多。
整个JUC里面最重要的还是前面3种共6个Java类,掌握好AQS和这6个常见类,JUC基本就没啥问题了。
感谢您的大驾光临!咨询技术、产品、运营和管理相关问题,请关注后留言。欢迎骚扰,不胜荣幸~
|