多个线程多个锁4

/**
 * Future模式有点类似于商品订单。比如在网购时,当看重某一件商品时,就可以提交订单,
 * 当订单处理完成后,在家里等待商品送货上门即可。或者说更形象的我们发送Ajax请求的时候,
 * 页面是异步的进行后台处理,用户无需一直等待请求的结果,可以继续浏览或操作其他内容。
 */
public class Main {

    public static void main(String[] args) {
        FutureClient fc = new FutureClient();
        Data data = fc.request("请求参数");
        System.out.println("请求发送成功!");
        System.out.println("做其他的事情。。。");
        String result = data.getRequest();
        System.out.println(result);
    }

}

public class FutureClient {

    public Data request(final String queryStr){
        /**
         * 1. 我想要一个代理对象(Data接口的实现类)先返回给发送请求的客户端,告诉他
         * 请求已经接收到,可以做其他的事情。
         */
        final FutureData futureData = new FutureData();

        /**
         * 2. 启动一个新的线程,去加载真实的数据,传递给这个代理对象
         */
        new Thread(new Runnable() {
            @Override
            public void run() {
                /**
                 * 这个新的线程可以去慢慢的加载真实对象,然后传递给代理对象
                 */
                RealData realData = new RealData(queryStr);
                futureData.setRealData(realData);
            }
        }).start();
        return futureData;
    }
}

public interface Data {
    String getRequest();
}
 
 
public class RealData implements Data {

    private String result;

    public RealData(String queryStr){
        System.out.println("根据" + queryStr + "进行查询,这是一个很耗时的操作。。");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("操作完毕,获取结果");
        result = "查询结果";
    }

    @Override
    public String getRequest() {
        return result;
    }
}
 
 
public class FutureData implements Data {

    private RealData realData;

    private boolean isReady = false;

    public synchronized void setRealData(RealData realData){
        //如果已经装载完毕了,就直接返回
        if(isReady){
            return;
        }
        //如果没装载,进行装载真实数据
        this.realData = realData;
        isReady = true;
        //进行通知
        notify();
    }
    @Override
    public synchronized String getRequest() {
        //如果没装载好,程序就一直处于阻塞状态
        while(!isReady){
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //装载好直接获取数据即可
        return this.realData.getRequest();
    }
}
 
 
import java.util.Random;
/**
 * Master-Worker模式是常用的并行计算模式。它的核心思想是系统由两类进程协作工作:
 * Master进程和Worker进程。Master负责接收和分配任务,Worker负责处理子任务。当各个
 * Worker子进程处理完成后,会将结果返回给Master,由Master做归纳和总结。其好处是能
 * 将一个大任务分解成若干个小任务,并行执行,从而提高系统的吞吐量。
 */
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;
            }
        }
    }
}
 
 
public class Task {

    private int id;
    private int price;

    public int getId() {
        return id;
    }

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

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }
}
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;

public class Master {

    /**
     * 1.有一个盛放任务的容器
     * 我们不需要阻塞。支持高并发
     */
    private ConcurrentLinkedQueue<Task> workQueue = new ConcurrentLinkedQueue<Task>();

    /**
     * 2.需要有一个盛放worker的集合
     */
    private HashMap<String,Thread> workers = new HashMap<String, Thread>();

    /**
     * 3.需要有一个盛放每一个worker执行任务的结果集合
     */
    private ConcurrentHashMap<String,Object> resultMap = new ConcurrentHashMap<String,Object>();

    /**
     * 4.构造方法
     */
    public Master(Worker worker,int workerCount){
        worker.setWorkQueue(this.workQueue);
        worker.setResultMap(this.resultMap);

        for (int i = 0;i < workerCount ; i++){
            this.workers.put(Integer.toString(i),new Thread(worker));
        }
    }

    /**
     * 5.需要一个提交任务的方法
     */
    public void submit(Task task){
        this.workQueue.add(task);
    }

    /**
     * 6.需要有一个执行方法,启动所有的worker方法去执行任务
     */
    public void execute(){
        for (Map.Entry<String,Thread> ms : workers.entrySet()){
            ms.getValue().start();
        }
    }

    /**
     * 7.判断是否运行结束的方法
     */
    public boolean isComplete(){
        for (Map.Entry<String,Thread> me : workers.entrySet()){
            if(me.getValue().getState() != Thread.State.TERMINATED){
                return false;
            }
        }
        return true;
    }

    /**
     * 8.计算结果方法
     */
    public int getResult(){
        int priceResult = 0;
        for (Map.Entry<String,Object> me : resultMap.entrySet()){
            priceResult += (Integer)me.getValue();
        }
        return priceResult;
    }

}
 
 
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;

public class Worker implements Runnable {

    private ConcurrentLinkedQueue<Task> workQueue;
    private ConcurrentHashMap<String,Object> resultMap;

    public void setWorkQueue(ConcurrentLinkedQueue<Task> workQueue) {
        this.workQueue = workQueue;
    }

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

    @Override
    public void run() {
        while(true){
            Task input = this.workQueue.poll();
            if (input == null) break;
            Object output = handle(input);
            this.resultMap.put(Integer.toString(input.getId()),output);
        }
    }

    private Object handle(Task input){
        Object output = null;
        try{
            Thread.sleep(500);
            output = input.getPrice();
        }catch (InterruptedException ex){
            ex.printStackTrace();
        }
        return output;
    }
}
 
 
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;

/**
 * 生产者和消费者也是一个非常经典的多线程模式,我们在实际开发中应用非常广泛的思想
 * 理念。在生产-消费模式中:通常由两类线程,及若干个生产者的线程和若干个消费者的线
 * 程。生产者线程负责提交用户请求,消费者线程则负责具体处理生产者提交的任务,在生
 * 产者和消费者之间通过共享内存缓冲区进行通信
 * */
public class Main {
    public static void main(String[] args) {
        /**
         * 内存缓冲区
         */
        BlockingQueue<Data> queue = new LinkedBlockingDeque<Data>(10);

        //生产者
        Provider p1 = new Provider(queue);
        Provider p2 = new Provider(queue);
        Provider p3 = new Provider(queue);
        //消费者
        Consumer c1 = new Consumer(queue);
        Consumer c2 = new Consumer(queue);
        Consumer c3 = new Consumer(queue);

        /**
         * 创建线程池运行,这是一个缓存的线程池,可以创建无穷大的线程,没有任务的时候
         * 不创建线程。空闲线程存活时间为60s(默认值)
         */
        ExecutorService cachePool = Executors.newCachedThreadPool();
        cachePool.execute(p1);
        cachePool.execute(p2);
        cachePool.execute(p3);
        cachePool.execute(c1);
        cachePool.execute(c2);
        cachePool.execute(c3);

        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        p1.stop();
        p2.stop();
        p3.stop();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
//        cachePool.shutdown();
//        cachePool.shutdownNow();

    }
}
 
 
public final class Data {

    private String id;
    private String name;

    public String getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public Data(String id,String name){
        this.id = id;
        this.name = name;
    }

    @Override
    public String toString() {
        return "{id:" + id + ", name:" + name + "}";
    }
}
 
 
import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public class Provider implements Runnable{
    //共享缓存区
    private BlockingQueue<Data> queue;
    /**
     * 多线程间是否启动变量,有强制从住内存中刷新的功能,即时返回线程的状态
     */
    private volatile boolean isRunning = true;
    //id生成器
    private static AtomicInteger count = new AtomicInteger();
    //随机对象
    private static Random r = new Random();

    public Provider(BlockingQueue queue){
        this.queue = queue;
    }

    @Override
    public void run() {
        while(isRunning){
            try {
                Thread.sleep(r.nextInt(1000));
                int id = count.incrementAndGet();
                Data data = new Data(Integer.toString(id),"数据" + id);
                System.out.println("当前线程:" + Thread.currentThread().getState() +
                        ",获取了数据,id为:" + id + "进行装载到公共缓冲区中...");
                if (!this.queue.offer(data,2,TimeUnit.SECONDS)){
                    System.out.println("提交缓冲区数据失败...");
                    //do something ... 比如重新提交
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public void stop(){
        this.isRunning = false;
    }
}
import java.util.Random;
import java.util.concurrent.BlockingQueue;

public class Consumer implements Runnable {

    private BlockingQueue<Data> queue;

    public Consumer(BlockingQueue queue){
        this.queue = queue;
    }

    private static Random r = new Random();

    @Override
    public void run() {
        while(true){
            try {
                Data data = this.queue.take();
                Thread.sleep(r.nextInt(1000));
                System.out.println("当前消费线程:" + Thread.currentThread().getName() +
                        ",消费成功,消费数据为id:" + data.getId());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
 
 
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 为了更好地控制多线程,JDK提供了一套线程框架Executor,帮助开发人员有效地进行线程控
 * 制。他们都在java.util.concurrent包中,是JDK并发包的核心。其中有一个比较重要的类:
 * Executors,它扮演这线程工厂的角色,我们通过Executors可以创建特定功能的线程池。
 *
 * Executors创建线程池方法:
 *
 * newFinedThreadPool()方法,该方法返回一个固定数量的线程池,该方法的线程数始终不变,
 * 当有一个任务提交时,若线程池中空闲,则立即执行,若没有,则会被暂缓在一个任务队列
 * 中等待有空闲的线程去执行。
 *
 * newSingleThreadExecutor()方法,创建一个线程的线程池,若空闲则执行,若没有空闲线
 * 程则暂缓在任务队列中。
 *
 * newCachedThreadPool()方法,返回一个可根据实际情况调整线程个数的线程池,不限制最大
 * 线程数量。若有任务,则创建线程,若无任务则不创建线程,如果没有任务则线程在60s后
 * 自动回收(空闲时间60s)。
 *
 * newScheduledThreadPool()方法,该方法返回一个SchededExecutorService对象,但该线程
 * 池可以指定线程的数量。
 *
 * 若Executors工厂类无法满足我们的需求,可以自己去创建自定义的线程池,其实Executors
 * 工厂类里面的创建线程方法其内部实现均是用了ThreadPoolExecutor这个类,这个类可以自
 * 定义线程。构造方法如下:
 * public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,
 * TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,
 * RejectedExecutionHandler handler){...}
 */
public class UseExcutors {
    public static void main(String[] args) {
        ExecutorService pool1 = Executors.newScheduledThreadPool(10);
        ExecutorService pool2 = Executors.newFixedThreadPool(10);
        ExecutorService pool3 = Executors.newSingleThreadExecutor();
        ExecutorService pool4 = Executors.newCachedThreadPool();
    }
}

 
 



猜你喜欢

转载自blog.csdn.net/jz1993/article/details/80723992
今日推荐