Java一个线程多个消费者(计算处理)

功能介绍

该程序模拟Java一个线程生产数据,分为四个线程来计算所生产的数据,生产完毕之后通知UI线程进行读取。这个代码很适合在实际运用过程中生产者生产较快,单个线程处理不过来的场景。后续可使用线程池进行优化。

import java.text.SimpleDateFormat;
import java.util.Date;
/*
* 日期:20200504
* 功能:模拟一个线程生产任务,生产完毕之后使用四个线程进行处理,上面四个线程处理完毕后将数据汇总到UI线程进行绘制
* 备注:这里为了方便查看代码结构,使用了内部类的方式来定义线程类,在实际使用过程中还是应该分开。
* 特点:仅仅利用notify和wait实现了类似qt的信号槽的方式来进行消息的通知
* */
public class WaitNotify {
    //这里定义两个锁对象,有将线程分组的思想
    static Object lock = new Object();
    static Object lockui = new Object();
    public static void main(String[] args) throws Exception {
        Thread waitThread = new Thread(new Wait(), "WaitThread");
        Thread waitThread1 = new Thread(new Wait(),"waitThread1");
        Thread waitThread2 = new Thread(new Wait(),"waitThread2");
        Thread waitThread3 = new Thread(new Wait(),"waitThread3");
        Thread waitui = new Thread(new WaitUi(),"waitui");

        waitThread.start();
        waitThread1.start();
        waitThread2.start();
        waitThread3.start();
        waitui.start();

        //这里需要延时一段时间,保证所有的wait线程都已经创建并处于wait状态
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //线程的生产者,250ms一次
        Thread notifyThread = new Thread(new Notify(), "NotifyThread");
        notifyThread.start();
    }

    //这个线程可模拟UI线程绘图的任务
    static class WaitUi implements Runnable{
        @Override
        public void run() {
            while (true){
                synchronized (lockui){
                    try {
                        lockui.wait();
                        System.out.println("uithread invoked!!!");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    //中间的计算者。这个线程可模拟多个线程计算的任务,计算完毕之后发送给UI线程。
    static class Wait implements Runnable {
        public void run() {
            // 加锁,拥有lock的Monitor
            while (true){
                synchronized (lock) {
                //wait,同时释放了lock的锁
                    try {
                        System.out.println(Thread.currentThread() + " Befort wait. " + new SimpleDateFormat("HH:mm:ss").format(new Date()));
                        lock.wait();
                    } catch (InterruptedException e) {
                    }
                    // 条件满足时,完成工作
                    System.out.println(Thread.currentThread() + " After wait . " + new SimpleDateFormat("HH:mm:ss").format(new Date()));
                }
                //执行耗时的任务
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (lockui){
                    lockui.notify();
                }

            }
        }
    }

    //最源头的生产者。由于TCP或UDP发送较快,因此通过多个线程来处理。
    static class Notify implements Runnable {
        public void run() {
            // 加锁,拥有lock的Monitor
            while (true){
                //执行耗时的生产者任务
                //比如UDP或者是TCP的接收任务
                try {
                    Thread.sleep(250);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (lock) {
                    // 获取lock的锁,然后进行通知,通知时不会释放lock的锁,
                    // 直到当前线程释放了lock后,WaitThread才能从wait方法中返回
                    System.out.println(Thread.currentThread() + " hold lock. notify @ " +
                            new SimpleDateFormat("HH:mm:ss").format(new Date()));
                    lock.notify();
                    System.out.println("Notify finish");
                }
            }
        }
    }
}

你可能感兴趣的:(Java,java,多线程,并发编程)