java多线程设计模式demo

Master-worker模式

Master-worker模式主要由两个角色组成,master主要负责任务的分发,worker主要是任务执行
在这里插入图片描述
demo
client

package com.example.demo.patterns.masterworker;

import com.alibaba.fastjson.JSON;

import java.util.Map;
import java.util.Random;
import java.util.concurrent.*;

/**
 * 主线程测试类
 */
public class Main {
    
    
    public static void main(String[] args) {
    
    
        int availableProcessors = Runtime.getRuntime().availableProcessors();
        System.out.println("核心线程数:"+ availableProcessors);
        int size = 20;
        //用来监听任务完成等待
        CountDownLatch countDownLatch = new CountDownLatch(size);
        MyWorker myWorker = new MyWorker();
        myWorker.setCountDownLatch(countDownLatch);
        //线程池
        ExecutorService executorService = Executors.newFixedThreadPool(availableProcessors);
        // 使用worker子类实现具体的业务,更加灵活
        Master master = new Master(myWorker, availableProcessors,countDownLatch,executorService);
        //提交10个任务
        for (int i = 1; i <= size; i++) {
    
    
            Task t = new Task();
            t.setId(i);
            master.submit(t);
        }
        //执行所有的worker
        master.execute();
        long start = System.currentTimeMillis();
        //全部的worker执行结束的时候去计算最后的结果
        if(master.isCompleted()){
    
    
            //获取结果对象
            ConcurrentHashMap<String, Object> resultMap = master.getResultMap();
            for (Map.Entry<String, Object> stringObjectEntry : resultMap.entrySet()) {
    
    
                System.out.println(JSON.toJSONString(stringObjectEntry.getValue()));
            }
        }
        long end = System.currentTimeMillis();
        System.out.println(String.format("执行时间:%d",end-start));
        executorService.shutdown();
    }
}

master

package com.example.demo.patterns.masterworker;


import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.*;

/**
 * Master
 */
public class Master<T> {
    
    
    //1、worker任务队列
    private ConcurrentLinkedQueue<T> workQueue = new ConcurrentLinkedQueue<T>();

    //2:使用hashmap去承载所有的worker对象 key:xxx value:worker任务线程
    private HashMap<String,Thread> workers = new HashMap<>();

    //3:用于存放子任务结果集
    private ConcurrentHashMap<String,T> resultMap = new ConcurrentHashMap<String, T>();

    private CountDownLatch countDownLatch;

    private ExecutorService executorService;

    /**
     *
     * @param worker worker对象
     * @param workerCount  需要worker执行的线程数
     */
    public Master(Worker worker, int workerCount, CountDownLatch countDownLatch, ExecutorService executorService){
    
    
        //主要用于对worker对象引入工作队列与结果队列
        worker.setWorkerQueue(this.workQueue);
        worker.setResultMap(this.resultMap);
        this.countDownLatch = countDownLatch;
        this.executorService = executorService;
        for (int i = 0; i < workerCount; i++) {
    
    
            //存入线程
            workers.put(String.format("worker[%d]",i), new Thread(worker));
        }
    }
    //存入任务队列,主要用worker去任务队列取值,然后执行,多任务多线程在
    //队列取值执行
    public void submit(T t){
    
    
        workQueue.add(t);
    }

    //执行方法
    public void execute(){
    
    
        //异步执行worker线程
        for (Map.Entry<String,Thread> entry: workers.entrySet()) {
    
    
            executorService.submit(entry.getValue());
        }
    }

    /**
     * 判断所有的worker是否执行完毕
     */
    public boolean isCompleted(){
    
    
        try {
    
    
            countDownLatch.await();
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        return true;
    }

    public ConcurrentHashMap<String, T> getResultMap() {
    
    
        return resultMap;
    }
}

worker

package com.example.demo.patterns.masterworker;

import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CountDownLatch;


/**
 * 抽象类,模板方法
 */
public abstract class Worker<T> implements Runnable {
    
    

    private ConcurrentLinkedQueue<T> workQueue;

    private ConcurrentHashMap<String, T> resultMap;

    protected CountDownLatch countDownLatch;

    public void setWorkerQueue(ConcurrentLinkedQueue<T> workQueue) {
    
    
        this.workQueue = workQueue;
    }

    public void setResultMap(ConcurrentHashMap<String, T> resultMap) {
    
    
        this.resultMap = resultMap;
    }

    @Override
    public void run() {
    
    
        //处理一个个任务
        while(true){
    
    
            //从队列中取出一个元素
            T input = this.workQueue.poll();
            //队列为空说明任务都已经执行完成
            if(null == input) break;
            //真正的去做业务处理
            T outPut = handle(input);
            //存放任务的结果
            this.resultMap.put(UUID.randomUUID().toString(), outPut);
        }
    }
    //单独抽出来 给子类重写,更加灵活
    public abstract T handle(T input);

    public void setCountDownLatch(CountDownLatch countDownLatch) {
    
    
        this.countDownLatch = countDownLatch;
    }
}

模板方法的实现类

package com.example.demo.patterns.masterworker;

import java.util.concurrent.TimeUnit;

public class MyWorker extends Worker<Task> {
    
    

    @Override
    public Task handle(Task task) {
    
    
        if(task == null){
    
    
            return null;
        }
        try {
    
    
            //莫你业务逻辑,对age进行计算赋值
            TimeUnit.SECONDS.sleep(2);
            task.setAge(task.getId()*10);
            super.countDownLatch.countDown();
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        return task;
    }
}

任务类

package com.example.demo.patterns.masterworker;

/**
 * 任务
 */
public class Task
{
    
    
    private int id;
    private int age;

    public int getId() {
    
    
        return id;
    }

    public void setId(int id) {
    
    
        this.id = id;
    }

    public int getAge() {
    
    
        return age;
    }

    public void setAge(int age) {
    
    
        this.age = age;
    }
}

运行结果:
可以看到12个任务,每个任务2秒,一共就执行2秒钟,说明了都是并行执行,并且一次就可以全部执行完了。

核心线程数:12
{
    
    "age":190,"id":19}
{
    
    "age":10,"id":1}
{
    
    "age":140,"id":14}
{
    
    "age":90,"id":9}
{
    
    "age":170,"id":17}
{
    
    "age":180,"id":18}
{
    
    "age":30,"id":3}
{
    
    "age":40,"id":4}
{
    
    "age":120,"id":12}
{
    
    "age":150,"id":15}
{
    
    "age":50,"id":5}
{
    
    "age":80,"id":8}
{
    
    "age":100,"id":10}
{
    
    "age":200,"id":20}
{
    
    "age":60,"id":6}
{
    
    "age":110,"id":11}
{
    
    "age":70,"id":7}
{
    
    "age":20,"id":2}
{
    
    "age":160,"id":16}
{
    
    "age":130,"id":13}
执行时间:4652

生产者消费者模式

client

package com.example.demo.patterns.queue;

import java.io.IOException;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;

public class Main {
    
    

    public static void main(String[] args) throws IOException {
    
    
        int availableProcessors = Runtime.getRuntime().availableProcessors();
        //生产者往队列放数据,队列为阻塞队列,队列大小
        int size = 10;
        BlockingQueue<Data> queue=new LinkedBlockingQueue<>(size);
        //3生产者 3个消费者
        Product product=new Product(queue);
        Product product1=new Product(queue);
        Product product2=new Product(queue);
        Consumer consumer=new Consumer(queue);
        Consumer consumer1=new Consumer(queue);
        Consumer consumer2=new Consumer(queue);
        ExecutorService executorService= Executors.newFixedThreadPool(availableProcessors);
        executorService.execute(product);
        executorService.execute(product1);
        executorService.execute(product2);
        executorService.execute(consumer);
        executorService.execute(consumer1);
        executorService.execute(consumer2);
        
//       System.in.read();

        try {
    
    
            Thread.sleep(2000);
            product.stop();
            product1.stop();
            product2.stop();
            executorService.shutdown();
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
    }
}

生产者

package com.example.demo.patterns.queue;

import com.alibaba.fastjson.JSON;

import java.util.Random;
import java.util.UUID;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
  *  生产者
 */
public class Product implements Runnable{
    
    

    private BlockingQueue<Data> queue;

    private volatile boolean running=true;

    public Product(BlockingQueue<Data> queue) {
    
    
        this.queue=queue;
    }

    @Override
    public void run() {
    
    
        while(running) {
    
    
            try {
    
    
                Thread.sleep(500);
                Data data=new Data();
                data.setName(UUID.randomUUID().toString());
                System.out.println(String.format("生产者生产数据[%s]", JSON.toJSONString(data)));
                queue.offer(data);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
        }
    }
    
    public void stop() {
    
    
        this.running=false;
    }
}

消费者

扫描二维码关注公众号,回复: 12575386 查看本文章
package com.example.demo.patterns.queue;

import com.alibaba.fastjson.JSON;

import java.util.Random;
import java.util.concurrent.BlockingQueue;

/**
 * 消费者
 */
public class Consumer implements Runnable{
    
    

    private volatile boolean running=true;

    private BlockingQueue<Data> queue;
    public Consumer(BlockingQueue<Data> queue) {
    
    
        this.queue=queue;
    }
    
    @Override
    public void run() {
    
    
        while (running) {
    
    
            try {
    
    
                Thread.sleep(2000);
                //没有数据会阻塞
                Data data=this.queue.take();
                System.out.println(String.format("消费者消费数据[%s]", JSON.toJSONString(data)));
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }            
        }
    }
}

数据

package com.example.demo.patterns.queue;

public class Data {
    
    
    private String name;

    public String getName() {
    
    
        return name;
    }

    public void setName(String name) {
    
    
        this.name = name;
    }
}

结果

生产者生产数据[{
    
    "name":"24d364f8-0c1c-45e1-bebc-a3083562c6e9"}]
生产者生产数据[{
    
    "name":"0a27207f-9776-491d-99d2-85f66342b44c"}]
生产者生产数据[{
    
    "name":"fc17c1a9-1ca6-4b3b-afc6-ccee30dae4e9"}]
生产者生产数据[{
    
    "name":"603882f2-9096-41e1-8b84-7af7b1b1ad68"}]
生产者生产数据[{
    
    "name":"ccf8bc1b-90bb-45ae-a27f-b39f4fe3f047"}]
生产者生产数据[{
    
    "name":"8dabb0c6-c4ee-469d-b14d-9928e3ef6580"}]
消费者消费数据[{
    
    "name":"24d364f8-0c1c-45e1-bebc-a3083562c6e9"}]
消费者消费数据[{
    
    "name":"fc17c1a9-1ca6-4b3b-afc6-ccee30dae4e9"}]
消费者消费数据[{
    
    "name":"0a27207f-9776-491d-99d2-85f66342b44c"}]
生产者生产数据[{
    
    "name":"f0f3351a-218b-40c0-9720-119c2a3c6bcd"}]
生产者生产数据[{
    
    "name":"02cb0cb8-5669-403c-b884-c7a882b512e4"}]
生产者生产数据[{
    
    "name":"d7012e1b-d6b0-4d1f-a519-087a83518caa"}]
消费者消费数据[{
    
    "name":"603882f2-9096-41e1-8b84-7af7b1b1ad68"}]
消费者消费数据[{
    
    "name":"ccf8bc1b-90bb-45ae-a27f-b39f4fe3f047"}]
消费者消费数据[{
    
    "name":"8dabb0c6-c4ee-469d-b14d-9928e3ef6580"}]
消费者消费数据[{
    
    "name":"d7012e1b-d6b0-4d1f-a519-087a83518caa"}]
消费者消费数据[{
    
    "name":"f0f3351a-218b-40c0-9720-119c2a3c6bcd"}]
消费者消费数据[{
    
    "name":"02cb0cb8-5669-403c-b884-c7a882b512e4"}]

furture模式

jdk1.8对furter进行优化,用completeablefurture,我们直接将completeablefurture例子

异步带返回值的逻辑,串行操作

package com.example.demo.completefuture;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CompletableFutureDemo {
    
    
    public static void main(String[] args) {
    
    
//      CompletableFuture.runAsync()
//      CompletableFuture.supplyAsync()
        ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

        //异步按照顺序执行,一个异步任务执行完成后接着执行
        //参数Supplier 接受生产者 只有返回值,代表数据的生产
        CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {
    
    
            try {
    
    
                Thread.sleep(3000L);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            return "张三";
        }, executorService);
        //参数为function,一个参数 一个返回值,代码函数式接口,处理逻辑然后返回
        CompletableFuture<String> completableFuture1 = completableFuture.thenApply(result -> {
    
    
            try {
    
    
                Thread.sleep(2000L);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            return result + "去";
        });
        CompletableFuture<String> completableFuture2 = completableFuture1.thenApply(result -> {
    
    
            try {
    
    
                Thread.sleep(1000L);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            return result + "吃火锅!";
        });
        //参数为Consumer,代表消费者对象
        completableFuture2.thenAccept(System.out::println);
        //抛异常执行的逻辑
        completableFuture2.exceptionally(e->{
    
    
            e.printStackTrace();
            return null;
        });
        //可以执行自己的业务逻辑
        System.out.println("主线程任务执行");
        //等待线程执行完成
        executorService.shutdown();
    }
}

主线程任务执行
张三去吃火锅!

异步不带返回值逻辑


public class CompletableFutureDemo2 {
    
    
    public static void main(String[] args) {
    
    
        ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
        CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(() -> {
    
    
            try {
    
    
                Thread.sleep(3000L);
                System.out.println("处理业务逻辑");
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
        },executorService);
        Consumer consumer = a-> System.out.println("任务处理完成");
        executorService.shutdown();
        completableFuture.thenAccept(consumer);
    }
}
处理业务逻辑
任务处理完成

还可以并行执行

package com.example.demo.completefuture;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CompletableFutureDemo3 {
    
    
    public static void main(String[] args) throws ExecutionException, InterruptedException {
    
    
        ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
        long start = System.currentTimeMillis();
        CompletableFuture<String> zs = CompletableFuture.supplyAsync(() ->{
    
    
            try {
    
    
                Thread.sleep(1000L);
                System.out.println("处理第一个逻辑");
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            return "处理第一个逻辑";
        },executorService);
        CompletableFuture<String> ls = CompletableFuture.supplyAsync(() -> {
    
    
            try {
    
    
                Thread.sleep(3000L);
                System.out.println("处理第二个逻辑");
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            return "处理第二个逻辑";
        },executorService);

        //代表两个任务任意一种,可以跟很多个任务,不只是两个,参数是一个数组
//        CompletableFuture.anyOf()
        //代表两者的所有
        CompletableFuture<Void> completableFuture = CompletableFuture.allOf(zs, ls);
        completableFuture.join();
        System.out.println("主函数执行时间:"+(System.currentTimeMillis()-start));

        System.out.println("第一个任务值:"+zs.get());
        System.out.println("第二个任务值:"+ls.get());
        executorService.shutdown();
    }
}
处理第一个逻辑
处理第二个逻辑
主函数执行时间:3046
第一个任务值:处理第一个逻辑
第二个任务值:处理第二个逻辑

猜你喜欢

转载自blog.csdn.net/qq_37904966/article/details/108305797
今日推荐