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集合的更多相关文章

  1. 廖雪峰Java11多线程编程-3高级concurrent包-5Atomic

    Atomic java.util.concurrent.atomic提供了一组原子类型操作: 如AtomicInteger提供了 int addAndGet(int delta) int increm ...

  2. 廖雪峰Java11多线程编程-3高级concurrent包-1ReentrantLock

    线程同步: 是因为多线程读写竞争资源需要同步 Java语言提供了synchronized/wait/notify来实现同步 编写多线程同步很困难 所以Java提供了java.util.concurre ...

  3. 廖雪峰Java11多线程编程-3高级concurrent包-6ExecutorService

    Java语言内置多线程支持: 创建线程需要操作系统资源(线程资源,栈空间) 频繁创建和销毁线程需要消耗大量时间 如果可以复用一个线程 线程池: 线程池维护若干个线程,处于等待状态 如果有新任务,就分配 ...

  4. 廖雪峰Java11多线程编程-3高级concurrent包-9Fork_Join

    线程池可以高效执行大量小任务: Fork/Join线程池可以执行一种特殊的任务: 把一个大任务拆成多个小任务并行执行 Fork/Join是在JDK 1.7引入的 示例:计算一个大数组的和 Fork/J ...

  5. 廖雪峰Java11多线程编程-3高级concurrent包-8CompletableFuture

    使用Future可以获得异步执行结果 Future<String> future = executor.submit(task); String result = future.get() ...

  6. 廖雪峰Java11多线程编程-3高级concurrent包-7Future

    JDK提供了ExecutorService接口表示线程池,可以通过submit提交一个任务. ExecutorService executor = Executors.newFixedThreadPo ...

  7. 廖雪峰Java11多线程编程-3高级concurrent包-3Condition

    Condition实现等待和唤醒线程 java.util.locks.ReentrantLock用于替代synchronized加锁 synchronized可以使用wait和notify实现在条件不 ...

  8. 廖雪峰Java11多线程编程-3高级concurrent包-2ReadWriteLock

    ReentrantLock保证单一线程执行 ReentrantLock保证了只有一个线程可以执行临界区代码: 临界区代码:任何时候只有1个线程可以执行的代码块. 临界区指的是一个访问共用资源(例如:共 ...

  9. 廖雪峰Java11多线程编程-2线程同步-3死锁

    1.线程锁可以嵌套 在多线程编程中,要执行synchronized块: 必须首先获得指定对象的锁 Java的线程锁是可重入的锁.对同一个对象,同一个线程,可以多次获取他的锁,即同一把锁可以嵌套.如以下 ...

随机推荐

  1. iOS开发静态库冲突——如何查看静态库(.O)中方法名

    1.bug产生 应用第三方静态库之后提示冲突错误: 2.bug分析 一般会提示哪两个库冲突: CameraShowGLView.o是自己创建的类编译生成的: libLechangeSDK.a是添加的静 ...

  2. IDEA web 开发环境搭建

    最近由eclipse 换 IDEA ,记录下开发环境的搭建过程. 1 配置idea vim 既可以使用IDEA方便的代码提示和调试功能,又可以方便使用vim编辑文件,安装完成后显示为vim Emula ...

  3. 剑指offer——01数组中重复的数字

    题目描述 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为 ...

  4. 什么是PoE、PSE、PD设备?

    一个完整的PoE系统包括供电端设备(PSE, Power Sourcing Equipment)和受电端设备(PD, Power Device)两部分.PSE设备是为以太网客户端设备供电的设备,同时也 ...

  5. 绿色版mysql 免安装使用(转载)

    MySQL绿色版的安装(mysql-5.6.22-win32.zip) Posted on 2015-01-31 23:21 卒子 阅读(10739) 评论(2) 编辑 收藏 由于工作需要最近要开始研 ...

  6. storm0.91集群部署

    事先配置2台服务器配置好zookeeper,在配置文件中用zookeeper管理集群,配置文件如下 配置文件/conf/storm.yaml supervisor.slots.ports: 对于每个S ...

  7. 使用python和tushare查询股票历史名称变更记录

    接口:namechange 描述:历史名称变更记录 注:tushare库下载和初始化教程,请查阅我之前的文章 输入参数 名称       |       类型       |       必选    ...

  8. JAVA时间工具类用法

    1.获得N天前的TIMESTAMP Calendar cl = Calendar.getInstance(); cl.add(Calendar.DAY_OF_YEAR, -7); Date date ...

  9. 多个for循环使用

    for循环 例子 语法 vue.js的for循环 <div id="myfor"><li v-for="student in studentList&q ...

  10. 整理下webapi的一些琐碎事情

    在使用webapi的时候我们会遇到一些问题比如 1.POST怎么请求 2.怎么兼容JSONP请求 3.怎么给指定端提供跨域的请求 4.怎么显示单独的models层的注释 问题一二其他人都玩的比较成熟的 ...