深入理解J.U.C

wait与notify实现阻塞队列

 

同步类容器在迭代的过程中如果被并发修改了内容,会抛出ConcurrentModificationException

同步类容器的状态都是串行化的

 

ConcurrentHashMap代替Hashtable
CopyOnWriteArrayList代替Vector 
并发的CopyOnWriteArraySet
ConcurrentLinkedQueue——高性能队列
LinkedBlockingQueue——阻塞形式的队列 
ArrayBlockingQueue,PriorityBlockingQueue,SynchronousQueue

 

ConcurrentHashMap 
ConcurrentSkipListMap(支持并发排序功能,弥补ConcurrentHashMap)

ConcurrentHashMap 内部 16个段(Segment),减少锁的粒度降低锁竞争,不在一个段上的写操作可以并发进行,共享变量被volatile修饰,不会出现脏读

 

Copy-On-Write容器 

写时复制容器,添加元素,并不直接添加,而是复制当前容器,在新的容器里添加元素,再把原容器的引用指向新的容器

并发的读不需要加锁,读写分离的思想,适合读多写少的场景

 

ConcurrentLinkedQueue 

通过无锁的方式,实现了高并发状态下的高性能。它是一个基于链表的无界线程安全队列,遵循FIFO原则,头是最先加入的,尾是最近加入的,不允许null元素且在通常情况下性能要好于BlockingQueue

 

ArrayBlockingQueue:基于数组的阻塞队列,内部维护一个定长数组(长度是需要定义的),以便缓存队列中的数据对象,其内部没有实现读写分离,也就意味着生产和消费不能完全并行,可以指定先进先出或者先进后出,是一个有界队列

LinkedBlockingQueue:基于链表的阻塞队列,其内部也维护着一个数据缓冲列队。它之所以能够高效的处理并发数据,是因为其内部用分离锁(读写分离两个锁)实现,从而实现生产者和消费者操作的完全并行运行,是一个无界队列(含参构造初始化则是有界的)

PriorityBlockingQueue:基于优先级的阻塞队列(优先级的判断通过构造函数传入的Compator对象来决定,也就是说传入队列的对象必须实现Comparable接口),内部控制线程同步的锁是公平锁,是一个无界队列

SynchronousQueue:一种没有缓冲的队列,生产者产生的数据直接会被消费者获取并消费

 

DelayQueue:带有延迟时间的Queue,其中的元素只有当其指定的延迟时间到了,才能够从队列中获取到元素。DelayQueue中的元素必须实现Delayed接口,是一个无界队列,主要用于对缓存超时数据进行移除、任务超时处理、空闲连接的关闭等

 1 package concurrent;
 2 
 3 import java.util.concurrent.Delayed;
 4 import java.util.concurrent.TimeUnit;
 5 
 6 public class Wangmin implements Delayed {
 7     private String name;
 8     private String id;// 身份证
 9     private long endTime;// 截止时间
10     private TimeUnit timeUnit = TimeUnit.SECONDS;// 定义时间工具类
11 
12     public Wangmin(String name,String id,long endTime){
13         this.name=name;
14         this.id=id;
15         this.endTime = endTime;
16     }
17 
18     public String getName(){
19         return this.name;
20     }
21     
22     public String getId(){
23         return this.id;
24     }
25 
26     //判断是否到了截止时间
27     @Override
28     public long getDelay(TimeUnit unit) {
29         return endTime - System.currentTimeMillis();
30     }
31     @Override
32     public int compareTo(Delayed delayed) {
33         Wangmin w = (Wangmin)delayed;
34         return this.getDelay(this.timeUnit) > w.getDelay(this.timeUnit) ? 1:0;
35     }
36 
37 }
 1 package concurrent;
 2 
 3 import java.util.concurrent.DelayQueue;
 4 
 5 public class WangBa implements Runnable {
 6     private DelayQueue<Wangmin> queue = new DelayQueue<>();
 7     public boolean yinye =true;
 8 
 9     public void shangji(String name,String id,int money){
10         Wangmin man = new Wangmin(name, id, 1000 * money + System.currentTimeMillis());
11         System.out.println(man.getName()+" 身份证"+man.getId()+"交钱"+money+"块,开始上机...");
12         this.queue.add(man);
13     }
14 
15     public void xiaji(Wangmin man){
16         System.out.println(man.getName()+" 身份证"+man.getId()+"时间到下机...");
17     }
18 
19     @Override
20     public void run() {
21         while(yinye){
22             try {
23                 Wangmin man = queue.take();
24                 xiaji(man);
25             } catch (InterruptedException e) {
26                 e.printStackTrace();
27             }
28         }
29     }
30 
31     public static void main(String args[]){
32         try{
33             System.out.println("网吧开始营业");
34             WangBa siyu = new WangBa();
35             Thread shangwang = new Thread(siyu);
36             shangwang.start();
37             siyu.shangji("路人A", "123", 1);
38             siyu.shangji("路人B", "234", 10);
39             siyu.shangji("路人C", "345", 5);
40         }
41         catch(Exception e){
42             e.printStackTrace();
43         }
44     }
45 
46 }

Future模式

1 package concurrent;
2 
3 public interface Data {
4     String getRequest();
5 }
 1 package concurrent;
 2 
 3 public class FutureClient {
 4     public Data request(final String queryStr){
 5         final FutureData futureData = new FutureData();
 6 
 7         new Thread(new Runnable() {
 8             @Override
 9             public void run() {
10                 RealData realData = new RealData(queryStr);
11                 futureData.setRealData(realData);
12             }
13         }).start();
14         return futureData;
15     }
16 }
 1 package concurrent;
 2 
 3 public class FutureData implements Data {
 4     private RealData realData ;
 5     private boolean isReady = false;
 6 
 7     public synchronized void setRealData(RealData realData) {
 8         if(isReady){
 9             return;
10         }
11         this.realData = realData;
12         isReady = true;
13         notify();
14     }
15     @Override
16     public synchronized String getRequest() {
17         while(!isReady){
18             try {
19                 wait();
20             } catch (InterruptedException e) {
21                 e.printStackTrace();
22             }
23         }
24         return this.realData.getRequest();
25     }
26 }
 1 package concurrent;
 2 
 3 public class RealData implements Data {
 4     private String result ;
 5 
 6     public RealData (String queryStr){
 7         System.out.println("根据" + queryStr + "进行查询,这是一个很耗时的操作..");
 8         try {
 9             Thread.sleep(5000);
10         } catch (InterruptedException e) {
11             e.printStackTrace();
12         }
13         System.out.println("操作完毕,获取结果");
14         result = "查询结果";
15     }
16 
17     @Override
18     public String getRequest() {
19         return result;
20     }
21 
22 }
 1 package concurrent;
 2 
 3 public class Main {
 4     public static void main(String[] args) throws InterruptedException {
 5         FutureClient fc = new FutureClient();
 6         Data data = fc.request("请求参数");
 7         System.out.println("请求发送成功!");
 8         System.out.println("去完成其他的事情...");
 9         String result = data.getRequest();
10         System.out.println(result);
11     }
12 }
13 /*
14 请求发送成功!
15 去完成其他的事情...
16 根据请求参数进行查询,这是一个很耗时的操作..
17 操作完毕,获取结果
18 查询结果
19  */

Master-Worker模式 

 1 package concurrent;
 2 
 3 public class Task {
 4     private int id;
 5     private int price ;
 6 
 7     public int getId() {
 8         return id;
 9     }
10     public void setId(int id) {
11         this.id = id;
12     }
13     public int getPrice() {
14         return price;
15     }
16     public void setPrice(int price) {
17         this.price = price;
18     }
19 
20 }
 1 package concurrent;
 2 
 3 import java.util.HashMap;
 4 import java.util.Map;
 5 import java.util.concurrent.ConcurrentHashMap;
 6 import java.util.concurrent.ConcurrentLinkedQueue;
 7 
 8 public class Master {
 9     //1.盛放任务的容器
10     private ConcurrentLinkedQueue<Task> workQueue = new ConcurrentLinkedQueue<>();
11     //2.盛放worker的集合
12     private HashMap<String, Thread> workers = new HashMap<>();
13     //3.盛放每一个worker执行任务的结果集合
14     private ConcurrentHashMap<String, Object> resultMap = new ConcurrentHashMap<>();
15 
16     //4.构造方法
17     public Master(Worker worker , int workerCount){
18         worker.setWorkQueue(this.workQueue);
19         worker.setResultMap(this.resultMap);
20         for(int i = 0; i < workerCount; i ++){
21             this.workers.put(Integer.toString(i), new Thread(worker));
22         }
23     }
24     //5.提交任务的方法
25     public void submit(Task task){
26         this.workQueue.add(task);
27     }
28     //6.执行的方法,启动所有的worker方法去执行任务
29     public void execute(){
30         for(Map.Entry<String, Thread> me : workers.entrySet()){
31             me.getValue().start();
32         }
33     }
34     //7.判断是否运行结束的方法
35     public boolean isComplete() {
36         for(Map.Entry<String, Thread> me : workers.entrySet()){
37             if(me.getValue().getState() != Thread.State.TERMINATED){
38                 return false;
39             }
40         }
41         return true;
42     }
43     //8.计算结果方法
44     public int getResult() {
45         int priceResult = 0;
46         for(Map.Entry<String, Object> me : resultMap.entrySet()){
47             priceResult += (Integer)me.getValue();
48         }
49         return priceResult;
50     }
51 }
 1 package concurrent;
 2 
 3 import java.util.concurrent.ConcurrentHashMap;
 4 import java.util.concurrent.ConcurrentLinkedQueue;
 5 
 6 public class Worker implements Runnable {
 7     private ConcurrentLinkedQueue<Task> workQueue;
 8     private ConcurrentHashMap<String, Object> resultMap;
 9 
10     public void setWorkQueue(ConcurrentLinkedQueue<Task> workQueue) {
11         this.workQueue = workQueue;
12     }
13     public void setResultMap(ConcurrentHashMap<String, Object> resultMap) {
14         this.resultMap = resultMap;
15     }
16     @Override
17     public void run() {
18         while(true){
19             Task input = this.workQueue.poll();
20             if(input == null) break;
21             Object output = handle(input);
22             this.resultMap.put(Integer.toString(input.getId()), output);
23         }
24     }
25     private Object handle(Task input) {
26         Object output = null;
27         try {
28             //处理任务的耗时,比如说进行数据库操作...
29             Thread.sleep(500);
30             output = input.getPrice();
31         } catch (InterruptedException e) {
32             e.printStackTrace();
33         }
34         return output;
35     }
36 
37 }
package concurrent;

import java.util.Random;

public class Main {
    public static void main(String[] args) {
        Master master = new Master(new Worker(), 20);
        Random r = new Random();
        for(int i = 1; i <= 100; i++){
            Task t = new Task();
            t.setId(i);
            t.setPrice(r.nextInt(1000));
            master.submit(t);
        }
        master.execute();
        long start = System.currentTimeMillis();
        while(true){
            if(master.isComplete()){
                long end = System.currentTimeMillis() - start;
                int priceResult = master.getResult();
                System.out.println("最终结果:" + priceResult + ", 执行时间:" + end);
                break;
            }
        }
    }
}

生产者-消费者模式 

 1 package concurrent;
 2 
 3 public final class Data {
 4     private String id;
 5     private String name;
 6 
 7     public Data(String id, String name){
 8         this.id = id;
 9         this.name = name;
10     }
11     public String getId() {
12         return id;
13     }
14     public void setId(String id) {
15         this.id = id;
16     }
17     public String getName() {
18         return name;
19     }
20     public void setName(String name) {
21         this.name = name;
22     }
23     @Override
24     public String toString(){
25         return "{id: " + id + ", name: " + name + "}";
26     }
27 
28 }
 1 package concurrent;
 2 
 3 import java.util.Random;
 4 import java.util.concurrent.BlockingQueue;
 5 import java.util.concurrent.TimeUnit;
 6 import java.util.concurrent.atomic.AtomicInteger;
 7 
 8 public class Provider implements Runnable{
 9     private BlockingQueue<Data> queue;
10     private volatile boolean isRunning = true;
11     private static AtomicInteger count = new AtomicInteger();
12     private static Random r = new Random();
13 
14     public Provider(BlockingQueue queue){
15         this.queue = queue;
16     }
17     @Override
18     public void run() {
19         while(isRunning){
20             try {
21                 Thread.sleep(r.nextInt(1000));
22                 int id = count.incrementAndGet();
23                 Data data = new Data(Integer.toString(id), "数据" + id);
24                 System.out.println("线程:" + Thread.currentThread().getName() + "获取了数据,id为:" + id + "装载到公共缓冲区中...");
25                 if(!this.queue.offer(data, 2, TimeUnit.SECONDS)){
26                     System.out.println("提交缓冲区数据失败...");
27                     //do something...
28                 }
29             } catch (InterruptedException e) {
30                 e.printStackTrace();
31             }
32         }
33     }
34     public void stop(){
35         this.isRunning = false;
36     }
37 }
 1 package concurrent;
 2 
 3 import java.util.Random;
 4 import java.util.concurrent.BlockingQueue;
 5 
 6 public class Consumer implements Runnable{
 7     private BlockingQueue<Data> queue;
 8     public Consumer(BlockingQueue queue){
 9         this.queue = queue;
10     }
11     private static Random r = new Random();
12 
13     @Override
14     public void run() {
15         while(true){
16             try {
17                 Data data = this.queue.take();
18                 Thread.sleep(r.nextInt(1000));
19                 System.out.println("消费线程:" + Thread.currentThread().getName() + "消费成功,消费数据id为:" + data.getId());
20             } catch (InterruptedException e) {
21                 e.printStackTrace();
22             }
23         }
24     }
25 }
 1 package concurrent;
 2 
 3 import java.util.concurrent.BlockingQueue;
 4 import java.util.concurrent.ExecutorService;
 5 import java.util.concurrent.Executors;
 6 import java.util.concurrent.LinkedBlockingQueue;
 7 
 8 public class Main {
 9     public static void main(String[] args) throws Exception {
10         BlockingQueue<Data> queue = new LinkedBlockingQueue<>(10);
11 
12         Provider p1 = new Provider(queue);
13         Provider p2 = new Provider(queue);
14         Provider p3 = new Provider(queue);
15 
16         Consumer c1 = new Consumer(queue);
17         Consumer c2 = new Consumer(queue);
18         Consumer c3 = new Consumer(queue);
19 
20         ExecutorService cachePool = Executors.newCachedThreadPool();
21         cachePool.execute(p1);
22         cachePool.execute(p2);
23         cachePool.execute(p3);
24         cachePool.execute(c1);
25         cachePool.execute(c2);
26         cachePool.execute(c3);
27         try {
28             Thread.sleep(3000);
29         } catch (InterruptedException e) {
30             e.printStackTrace();
31         }
32         p1.stop();
33         p2.stop();
34         p3.stop();
35         try {
36             Thread.sleep(2000);
37         } catch (InterruptedException e) {
38             e.printStackTrace();
39         }
40     }
41 }

 

转载于:https://www.cnblogs.com/sakura1027/p/8798778.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值