多线程 生产者消费者 多生产多消费

制作吐司的一个例子,分为制作, 抹油, 涂果酱三部分,至少使用三个线程执行不同的任务。

用的阻塞队列来实现

吐司类

package com.thread.Demo01;

// 吐司
public class Toast {
    // 吐司的三种状态:干燥, 抹油, 果酱
    public enum Status {DRY, BUTTERED, JAMMED}
    private Status status = Status.DRY;
    private final int id;

    public Toast(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }

    public Status getStatus() {
        return status;
    }

    public void buttered(){
        this.status = Status.BUTTERED;
    }

    public void Jammed() {
        this.status = Status.JAMMED;
    }

    @Override
    public String toString() {
        return "Toast{" +
                "status=" + status +
                ", id=" + id +
                '}';
    }
}

制作吐司线程

package com.thread.Demo01;

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

// 制作吐司
public class Toaster implements Runnable {
    private BlockingQueue<Toast> toastBlockingQueue;
    private static int count = 0;

    public Toaster(BlockingQueue<Toast> toastBlockingQueue) {
        this.toastBlockingQueue = toastBlockingQueue;
    }

    @Override
    public void run() {
        try {
            while (!Thread.interrupted()){
                Toast toast = new Toast(++count);
                System.out.println("Toaster make " + toast);
                toastBlockingQueue.put(toast);
                TimeUnit.MILLISECONDS.sleep(new Random().nextInt(150));
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

涂油类

package com.thread.Demo01;

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

public class Butterer implements Runnable {
    private BlockingQueue<Toast> dryQueue, butteredQueue;

    public Butterer(BlockingQueue<Toast> dryQueue, BlockingQueue<Toast> butteredQueue) {
        this.dryQueue = dryQueue;
        this.butteredQueue = butteredQueue;
    }

    @Override
    public void run() {
        try {
            while (!Thread.interrupted()){
                Toast take = dryQueue.take();
                take.buttered();
                System.out.println("Butterer buttered " + take);
                butteredQueue.put(take);
                TimeUnit.MILLISECONDS.sleep(new Random().nextInt(150));
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}

涂果酱类

package com.thread.Demo01;

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

public class Jammer implements Runnable {
    private BlockingQueue<Toast> butterQueue, JammerQueue;

    public Jammer(BlockingQueue<Toast> butterQueue, BlockingQueue<Toast> jammerQueue) {
        this.butterQueue = butterQueue;
        JammerQueue = jammerQueue;
    }

    @Override
    public void run() {
        try {
            while (!Thread.interrupted()) {
                Toast toast = butterQueue.take();
                toast.Jammed();
                System.out.println("Jammer jammed " + toast);
                JammerQueue.put(toast);
                TimeUnit.MILLISECONDS.sleep(new Random().nextInt(150));
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

消费者类

package com.thread.Demo01;

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

public class Eater implements Runnable {
    private BlockingQueue<Toast> jammerQueue, finishQueue;

    public Eater(BlockingQueue<Toast> jammerQueue, BlockingQueue<Toast> finishQueue) {
        this.jammerQueue = jammerQueue;
        this.finishQueue = finishQueue;
    }

    @Override
    public void run() {
        try {
            while (!Thread.interrupted()) {
                Toast toast = jammerQueue.take();
                if (toast.getStatus() != Toast.Status.JAMMED) {
                    System.out.println(">>>>>> ERROR" + toast);
                } else {
                    System.out.println("Eater eat " + toast);
                }
                TimeUnit.MILLISECONDS.sleep(new Random().nextInt(150));
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

测试类

package com.thread.Demo01;

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

public class ToastMatic {
    public static void main(String[] args) {
        BlockingQueue<Toast>
                dryQueue = new LinkedBlockingQueue<>(),
                butterQueue = new LinkedBlockingQueue<>(),
                jammerQueue = new LinkedBlockingQueue<>(),
                finishQueue = new LinkedBlockingQueue<>();
        ExecutorService service = Executors.newCachedThreadPool();
        service.execute(new Toaster(dryQueue));
        service.execute(new Toaster(dryQueue));
        service.execute(new Butterer(dryQueue, butterQueue));
        service.execute(new Butterer(dryQueue, butterQueue));
        service.execute(new Butterer(dryQueue, butterQueue));
        service.execute(new Jammer(butterQueue, jammerQueue));
        service.execute(new Eater(jammerQueue, finishQueue));
        service.execute(new Eater(jammerQueue, finishQueue));
        service.execute(new Eater(jammerQueue, finishQueue));
    }
}

猜你喜欢

转载自blog.csdn.net/JOKER_SAMA/article/details/81637244