>JUC ? 就是Java API 中这三个包的简称:

>concurrent 包

1.线程池

对于N个任务,可以来一个任务就开辟一个线程。而线程池的思想是,用一个线程池去处理这N个任务。

使用线程池一般步骤:

  • 使用Executor类的静态方法创建ExecutorService对象,该对象就代表一个线程池。
  • 使用这个线程池的execute 或submit 方法来提交一个任务,而这个任务就是一个线程。
  • 要关闭一个线程池,可以使用ExecutorService对象的shutdown 方法。
public class TestThreadPool {public static void main(String[] args) {// 固定大小线程池Executor threadPool = Executors.newFixedThreadPool(4);// 拓展线程池 根据线程使用率进行清空Executor threadPool2 = Executors.newCachedThreadPool();// 单线程Executor threadPool3 = Executors.newSingleThreadExecutor();Random r = new Random();Runnable target = new Runnable() {@Overridepublic void run() {for (int i = 0; i < 10; i++) {System.out.println(Thread.currentThread().getName() + "第" + i + "个任务");try {Thread.sleep(r.nextInt(500));} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}};for (int i = 0; i < 10; i++) {// new Thread(target).start();threadPool2.execute(target);}}
}

2.future

前面学习的“Future提前完成任务模式”。其实实现了一种异步计算结果,主程序不受调用程序处理时间长短而控制,提前返回控制权。而这里JUC提供的Callable和Future就是完成了这一功能。

Callable类似于一个增强的Runnable 接口,与之不同的是Callable提供了一个call() 方法来执行线程代码,call() 方法可以有返回值,也可以声明式地抛出异常。

为什么要使用Future?多线程的返回值问题

使用流派:

  1. 继承Callable接口,实现call() 方法,这个call() 方法不仅是线程的执行体,也可以有返回值。
  2. 使用FutureTask 对象包装Callable 对象,因为FutureTask实现了Runnable 接口,可以作为Thread 的执行载体。FutureTask封装了call() 方法的返回值。
  3. 使用FutureTask 对象作为Thread 载体创建线程。
  4. 使用FutureTask 对象的get() 方法获得线程执行结果。
public class TestCallable {public static void main(String[] args) throws Exception {TestCallable tc = new TestCallable();tc.go();}private void go() throws Exception {// 一个小注意点:内部类也是成员,非静态的情况不能直接在main中new,成员方法中可以MyThread mt = new MyThread();FutureTask<Integer> ft = new FutureTask<Integer>(mt);new Thread(ft).start();System.out.println("我想干点别的,等待结果来了之后我拿结果");// Integer i = ft.get();//直接写get(),任务结束后取值Integer j = ft.get(1, TimeUnit.SECONDS);// 拿结果的最长等待时间,如果超时等不到就报错。// Exception in thread "main"// java.util.concurrent.TimeoutExceptionSystem.out.println(j);}/*** 增强版线程: 1、可以有返回值 2、可以throws 异常*/class MyThread implements Callable<Integer> {@Overridepublic Integer call() throws Exception {Thread.sleep(2000);return 1;}}
}

如何在线程池中使用Callable 和 Future?

线程池中,也可以使用Callable和Future,用法很简单。只是不必使用Future 的实现类FutureTask ,因为线程池可以直接提交一个Callable任务,而不像使用Thread 必须有一个Runnable 载体。

使用流派:

  1. 创建线程池、Callable 对象。
  2. 使用线程池 submit() 提交Callable 对象。返回Future对象。
  3. 使用Future对象的 get() 方法,获得返回值。
public class TestCallableThreadPool {public static void main(String[] args) {TestCallableThreadPool t = new TestCallableThreadPool();t.go();}private void go() {ExecutorService threadPool = Executors.newCachedThreadPool();Future<String> future = threadPool.submit(new MyThread());try {String string = future.get();System.out.println(string);} catch (InterruptedException | ExecutionException e) {// TODO Auto-generated catch blocke.printStackTrace();}}class MyThread implements Callable<String> {@Overridepublic String call() throws Exception {Thread.sleep(2000);return "hello world";}}
}

3.同步容器、并发容器

>3.1

传统的容器比如线程不安全的ArrayList:

线程安全的Vector(区别就是加了锁),即使需要线程安全的容器,我们也不使用Vector,使用工具类Collections转换为线程安全的类:

典型的代理模式实现,对ArrayList 的方法进行包装,最终干活的还是ArrayList:

>3.2迭代时删除问题

首先,不要在 foreach 循环里进行元素的 remove/add 操作

public class TestTh {public static void main(String[] args) {List<String> list = new ArrayList<>();list = Collections.synchronizedList(list);for (int i = 0; i < 100; i++) {list.add(String.valueOf(i));}for (String string : list) {if (string.equals("30")) {System.out.println(string);list.remove(string);}}}}

会报错:

并发容器CopyOnWriteArrayList,解决遍历时修改的问题,满足了读一致性,

注意与同步容器(解决线程安全问题)区分:

public class Test {public static void main(String[] args) {Test t = new Test();t.go();}private void go() {V v = new V();new Thread(new Runnable() {@Overridepublic void run() {v.show();}}).start();new Thread(new Runnable() {@Overridepublic void run() {v.modify();}}).start();}class V {// 两个线程同时操作一个线程(一个线程监测,一个修改就报错),也有问题// private List<Integer> list = new ArrayList<>();// 并发容器,与前面的同步容器进行区分private List<Integer> list = new CopyOnWriteArrayList<>();public V() {for (int i = 0; i < 100; i++) {list.add(i);}// list=Collections.synchronizedList(list);}public void show() {for (int i : list) {System.out.println(i);try {Thread.sleep(20);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}public void modify() {for (int i = 200; i < 300; i++) {list.add(i);}try {Thread.sleep(20);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
}

>3.3使用并发容器ConcurrentHashMap设计一个缓存:

Java 并发(JUC 包-02)相关推荐

  1. Java并发编程包中atomic的实现原理

    转载自   Java并发编程包中atomic的实现原理 这是一篇来自粉丝的投稿,作者[林湾村龙猫]最近在阅读Java源码,这一篇是他关于并发包中atomic类的源码阅读的总结.Hollis做了一点点修 ...

  2. JAVA并发类包介绍

    JAVA并发Apl介绍合集 1. java.util.concurrent包 1.1 Executors线程池 1.2 Queues队列 1.3 Concurrent Collections 1.4 ...

  3. Java多线程 -- JUC包源码分析2 -- Copy On Write/CopyOnWriteArrayList/CopyOnWriteArraySet

    本人新书出版,对技术感兴趣的朋友请关注: https://mp.weixin.qq.com/s/uq2cw2Lgf-s4nPHJ4WH4aw 上1篇讲述了Java并发编程的第1个基本思想–CAS/乐观 ...

  4. java并发-JUC

    CAS 无锁,乐观锁,自旋锁,轻量级锁 定义 Compare and Swap,是基于硬件级别的指令实现的同步原语,Java并发包java.utile.concurrent许多同步类基于CAS构建 c ...

  5. Java并发JUC(java.util.concurrent)集合不安全

  6. 多线程十 JUC包下的常用工具类

    JUC包下的常用工具类 1. CountDownLatch-闭锁 2. CyclicBarrier-循环栅栏 3. Semaphore-信号量 4. Exchanger-线程数据交换器 这篇文章主要是 ...

  7. 6.juc包下的原子类AtomicInteger,AtomicLong等AtomicXXX介绍

     在介绍juc中的原子类之前,先看看官方文档对java.util.concurrent.atomic包的介绍官方文档地址这里截取翻译之后的部分描述 1. 支持对单个变量进行无锁线程安全编程 2. 类的 ...

  8. JAVA并发编程JUC基础学习(简介)

    2019独角兽企业重金招聘Python工程师标准>>> 之前写过一篇并发编程的简单实例应用,Future快速实现并发编程,可以很快的在自己的项目中应用,但并不系统,之前说过总结一篇( ...

  9. java并发编程(二十一)----(JUC集合)CopyOnWriteArraySet和ConcurrentSkipListSet介绍

    转载自  java并发编程(二十一)----(JUC集合)CopyOnWriteArraySet和ConcurrentSkipListSet介绍 这一节我们来接着介绍JUC集合:CopyOnWrite ...

最新文章

  1. python时间日期字符串各种
  2. 批量生成 Gitee 仓库克隆命令的方法
  3. ABP+AdminLTE+Bootstrap Table权限管理系统第八节--ABP错误机制及AbpSession相关
  4. centos 下 r graphics绘图如何保存_如何选购一台合适的商务笔记本电脑
  5. java并发程序死锁检测_Java并发:隐藏的线程死锁
  6. html css布局之float和Flexbox
  7. weui和jquery weui的区别、下载和在项目中的引用、使用、应用
  8. 2022年,全网最真实的软件测试面试题
  9. Brachistochrone curve(传说中的最速降线)
  10. 数学之美:常用的微分,求导和积分公式大总结
  11. YUV RGB 相互转换矩阵
  12. 一个AI小白如何理解近似匹配检索
  13. Hexo-fluid主题添加51LA统计
  14. 电路交换,报文交换,分组交换简介与优缺点
  15. [国家地理百年纪念典藏全100集][MKV][225M/1][国英双语中字]
  16. hp刀片服务器重装,HP刀片服务器安装系统教程b280c.doc
  17. 店铺一定要注意店铺质量|百择电商
  18. 什么是词向量?(NPL入门)
  19. redis 内网配置连接
  20. 钛碳化铝(Ti3AlC2)在实验检测领域中的应用

热门文章

  1. 线上Go项目的Docker镜像应该怎么构建?
  2. IDEA项目创建Mapper的xml文件的方法
  3. 接口与抽象类的区别和联系
  4. kafka手动调整分区副本数
  5. springbatch导出mysql数据到外部文件
  6. springcloud使用feign进行远程服务调用
  7. Xilinx Zynq-7000 嵌入式系统设计与实现
  8. WebSocket与http长连接的区别
  9. Windows下常用的100个CMD指令以及常见的操作
  10. 《C++之那些年踩过的坑(附录一)》