• Java并发编程-线程间通讯示例


    在Java中线程间通讯有多种方式,我这里列出一些常用方式,并用代码的方式展示他们是如何实现的:

    • 共享变量
    • wait, notify,notifyAll(这3个方法是Object对象中的方法,且必须与synchronized关键字结合使用)
    • CyclicBarrier、CountDownLatch
    • 利用LockSupport
    • Lock/Condition机制
    • 管道,创建管道输出流PipedOutputStream和管道输入流PipedInputStream

    示例一:

    package com.zhi.test;
    
    import java.util.concurrent.CountDownLatch;
    import java.util.concurrent.atomic.AtomicInteger;
    
    import org.junit.Test;
    
    /**
     * Java多线程-线程通讯示例<br>
     * flag作为共享变量JobB执行,notify通知Job执行,CountDownLatch通知主线程执行
     * 
     * @author 张远志
     * @since 2020年5月4日21:51:24
     *
     */
    public class ThreadTest2 {
        private CountDownLatch latch;
        private volatile boolean flag = true;
        private Object lock = new Object();
        private AtomicInteger num = new AtomicInteger(0);
    
        class JobA implements Runnable {
            @Override
            public void run() {
                synchronized (lock) {
                    flag = false;
                    if (num.get() != 3) {
                        try {
                            lock.wait(); // wait方法会释放锁
                        } catch (InterruptedException e) {
                        }
                    }
                    System.out.println("任务A收到通知,继续执行作业");
                }
                latch.countDown();
            }
        }
    
        class JobB implements Runnable {
            @Override
            public void run() {
                while (flag) { // 保证JobA先申请到锁
    
                }
                synchronized (lock) {
                    for (int i = 1; i <= 5; i++) {
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                        }
                        int a = num.incrementAndGet();
                        System.out.println("任务B第" + i + "次执行,num值为:" + a);
                        if (a == 3) {
                            lock.notify(); // 唤醒JobB线程,notify方法不会释放锁
                        }
                    }
                }
                latch.countDown();
            }
        }
    
        @Test
        public void test() {
            latch = new CountDownLatch(2);
            new Thread(new JobA()).start();
            new Thread(new JobB()).start();
            try {
                latch.await(); // 保证2个线程都执行完毕
            } catch (InterruptedException e) {
            }
        }
    }

      结果输出:

    任务B第1次执行,num值为:1
    任务B第2次执行,num值为:2
    任务B第3次执行,num值为:3
    任务B第4次执行,num值为:4
    任务B第5次执行,num值为:5
    任务A收到通知,继续执行作业

    示例二:

    package com.zhi.test;
    
    import java.util.concurrent.CountDownLatch;
    import java.util.concurrent.locks.LockSupport;
    
    import org.junit.Test;
    
    /**
     * Java多线程-线程通讯示例,利用LockSupport
     * 
     * @author 张远志
     * @since 2020年5月4日21:51:24
     *
     */
    public class ThreadTest3 {
        private CountDownLatch latch;
        private volatile int num = 0;
        private Thread ta;
        private Thread tb;
    
        class JobA implements Runnable {
            @Override
            public void run() {
                if (num != 3) {
                    LockSupport.park();
                }
                System.out.println("任务A收到通知,继续执行作业");
                latch.countDown();
            }
        }
    
        class JobB implements Runnable {
            @Override
            public void run() {
                for (int i = 1; i <= 5; i++) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                    }
                    num++;
                    System.out.println("任务B第" + i + "次执行,num值为:" + num);
                    if (num == 3) {
                        LockSupport.unpark(ta); // unpark会立即激活传入线程
                    }
                }
                latch.countDown();
            }
        }
    
        @Test
        public void test() {
            latch = new CountDownLatch(2);
            ta = new Thread(new JobA());
            tb = new Thread(new JobB());
            ta.start();
            tb.start();
            try {
                latch.await(); // 保证2个线程都执行完毕
            } catch (InterruptedException e) {
            }
        }
    }
  • 相关阅读:
    20145334赵文豪 《Java程序设计》第3周学习总结
    2145334赵文豪《Java程序设计》第2周学习总结
    20145334赵文豪 《Java程序设计》第1周学习总结
    20145326蔡馨熤《信息安全系统设计基础》第0周学习总结
    20145326 《Java程序设计》课程总结
    20145326 《Java程序设计》实验五——Java网络编程及安全实验报告
    20145326 《Java程序设计》第10周学习总结
    20145326 《Java程序设计》第9周学习总结
    20145326实验四 Android开发基础
    20145326蔡馨熠 实验三 "敏捷开发与XP实践"
  • 原文地址:https://www.cnblogs.com/zhi-leaf/p/12828465.html
Copyright © 2020-2023  润新知