廖雪峰Java11多线程编程-3高级concurrent包-4Concurrent集合
1. Concurrent
用ReentrantLock+Condition实现Blocking Queue。
class TaskQueue{
final Queue<String> queue = new LinkedList<>();
final Lock lock = new ReentrantLock();
final Condition noEmpty = lock.newCondition();
public String getTask(){...}
public void addTask(String name){...}
}
Blocking Queue:当一个线程调用这个Queue的getTask()时,该方法内部可能让给线程变成等待状态,直到条件满足。线程被唤醒以后,getTask()才会返回。
而java.util.concurrent提供了线程安全的Blocking集合,如ArrayBlockingQueue就已经包含了一个线程安全的BlockingQueue。
2. 示例
当我们使用BlockingQueue的时候,我们的代码又被大大的简化了。take()是BlockingQueue提供的一个Blocking方法。当我们调用take()方法的时候,在内部可能会被阻塞,直到条件满足线程才会返回。
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
class WorkerThread extends Thread{
BlockingQueue<String> taskQueue;
public WorkerThread(BlockingQueue<String> taskQueue){
this.taskQueue = taskQueue;
}
public void run(){
while(!isInterrupted()){
String name;
try{
name = taskQueue.take();
}catch (InterruptedException e){
break;
}
String result = "Hello,"+name+"!";
System.out.println(result);
}
}
}
public class Main{
public static void main(String[] args) throws Exception{
//在main方法中,我们不需要自己编写一个BlockingQueue。我们可以直接使用ArrayBlockingQueue,然后向Queue中添加3个任务
BlockingQueue<String> taskQueue = new ArrayBlockingQueue<>(1000);
WorkerThread worker = new WorkerThread(taskQueue);
worker.start();
taskQueue.put("Bob");
Thread.sleep(1000);
taskQueue.put("Alice");
Thread.sleep(1000);
taskQueue.put("Tim");
Thread.sleep(1000);
worker.interrupt();
worker.join();
System.out.println("END");
}
}

## 3.java.util.concurrent提供了线程安全的Blocking集合

## 4.java.util.Collections工具类
java.util.Collections工具类还提供了旧的线程安全集合转换器:
如把一个HashMap转化为一个线程安全的Map。实际上使用一个线程类,包装了非线程安全的map,然后对所有的读写方法都用synchronized加锁,这样获得了线程安全的集合。它的性能比Concurrent低很多,不推荐使用。。
```#java
Map unsafeMap = new HashMap();
Map threadSafeMap = Collections.synchronizedMap(unsafeMap);
```
5. 总结:
使用java.util.concurrent提供的Blocking集合可以简化多线程编程
- 多线程同时访问Blocking集合是安全的
- 尽量使用JDK提供的concurrent集合,避免自己编写同步代码
廖雪峰Java11多线程编程-3高级concurrent包-4Concurrent集合的更多相关文章
- 廖雪峰Java11多线程编程-3高级concurrent包-5Atomic
Atomic java.util.concurrent.atomic提供了一组原子类型操作: 如AtomicInteger提供了 int addAndGet(int delta) int increm ...
- 廖雪峰Java11多线程编程-3高级concurrent包-1ReentrantLock
线程同步: 是因为多线程读写竞争资源需要同步 Java语言提供了synchronized/wait/notify来实现同步 编写多线程同步很困难 所以Java提供了java.util.concurre ...
- 廖雪峰Java11多线程编程-3高级concurrent包-6ExecutorService
Java语言内置多线程支持: 创建线程需要操作系统资源(线程资源,栈空间) 频繁创建和销毁线程需要消耗大量时间 如果可以复用一个线程 线程池: 线程池维护若干个线程,处于等待状态 如果有新任务,就分配 ...
- 廖雪峰Java11多线程编程-3高级concurrent包-9Fork_Join
线程池可以高效执行大量小任务: Fork/Join线程池可以执行一种特殊的任务: 把一个大任务拆成多个小任务并行执行 Fork/Join是在JDK 1.7引入的 示例:计算一个大数组的和 Fork/J ...
- 廖雪峰Java11多线程编程-3高级concurrent包-8CompletableFuture
使用Future可以获得异步执行结果 Future<String> future = executor.submit(task); String result = future.get() ...
- 廖雪峰Java11多线程编程-3高级concurrent包-7Future
JDK提供了ExecutorService接口表示线程池,可以通过submit提交一个任务. ExecutorService executor = Executors.newFixedThreadPo ...
- 廖雪峰Java11多线程编程-3高级concurrent包-3Condition
Condition实现等待和唤醒线程 java.util.locks.ReentrantLock用于替代synchronized加锁 synchronized可以使用wait和notify实现在条件不 ...
- 廖雪峰Java11多线程编程-3高级concurrent包-2ReadWriteLock
ReentrantLock保证单一线程执行 ReentrantLock保证了只有一个线程可以执行临界区代码: 临界区代码:任何时候只有1个线程可以执行的代码块. 临界区指的是一个访问共用资源(例如:共 ...
- 廖雪峰Java11多线程编程-2线程同步-3死锁
1.线程锁可以嵌套 在多线程编程中,要执行synchronized块: 必须首先获得指定对象的锁 Java的线程锁是可重入的锁.对同一个对象,同一个线程,可以多次获取他的锁,即同一把锁可以嵌套.如以下 ...
随机推荐
- .Net Core 部署之一 《CentOS 从GitHub/Gitee 等源代码网站部署Web网站》
先看下楼主从某阿打折购买的渣渣服务器 lsb_release -a 一.安装dotnet-SDK 注册微软的服务 sudo rpm -Uvh https://packages.microsoft.co ...
- 10、 导出python脚本进行数据驱动的接口测试
postman自带脚本导出功能,对于代码小白来说,可以不错的学习代码级接口测试 第一步:输入接口地址,点击send 第二步:点击code,导出脚本文件,为python脚本 第三步:安装python3以 ...
- __attribute__ (( __cleanup__))
一.简单说明: cleanup作为__attribute__属性中的一个可选属性值 其作用是当其声明的变量离开了其生命周期,那么 会自动调用你所指定的销毁函数 二.例子: #include <s ...
- Cortex-M3的异常/中断屏蔽寄存器组
转自 1. Cortex-M3的异常/中断屏蔽寄存器组 注:只有在特权级下,才允许访问这3个寄存器. 名 字 功能描述 PRIMASK 只有单一比特的寄存器.置为1后,就关掉所有可屏蔽异常,只剩下NM ...
- 剑指offer——28对称的二叉树
题目描述 请实现一个函数,用来判断一颗二叉树是不是对称的.注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的. 题解: 使用正常前序遍历与反向的前序遍历进行比较结果即可,注意,需将空 ...
- docker 错误failed to open stream: Permission denied 解决方法
在服务器上面.运行docker时,php目录会发生权限问题解决方法如下: 1:进入php目录下面 docker exec -ti php56 /bin/bash #进入php容器 chown -R w ...
- Java设计模式(一)外观模式(门面模式)- 结构型模式
模式的定义 门面模式(Facade Pattern)也叫做外观模式,是一种比较常用的封装模式,其定义如下:要求一个子系统的外部与其内部通信必须通过一个统一的对象进行.门面模式提供一个高层次的接口,使得 ...
- 天道神诀---DHCP服务(上篇)
DHCP DHCP(Dynamic Host Configuration Protocol, 动态主机配置协议),被应用在局域网环境中,主要作用是集中的管理.分配IP地址,使网路环境中的主机动态的获得 ...
- HDU 4325 离散化+树状数组 或者 不使用树状数组
题意:给出一些花的开放时间段,然后询问某个时间点有几朵花正在开放. 由于ti<1e9,我们需要先将时间离散化,然后将时间点抽象为一个数组中的点,显然,我们需要进行区间更新和单点查询,可以考虑线段 ...
- Datagrid 的 SelectItem 和 SelectValue 如何区分、DataContext 和 ItemSource 在绑定时该绑哪个?
1.selecteditem.selectedvalue.selectedvaluepath三个属性 场景: class T { public string A { get; set; } publi ...