zoukankan      html  css  js  c++  java
  • 三个线程a、b、c并发运行,b,c需要a线程的数据怎么实现(semaphore.acquire()方法和permit标记)

    public class ThreadCommunication {
        /**
         * 三个线程a、b、c并发运行,b,c需要a线程的数据怎么实现
         *
         * 根据问题的描述,通过三个线程,ThreadA ThreadB ThreadC
         * ThreadA用于初始化数据num,只有num初始化完成之后再让ThreadB和ThreadC获取到初始化的变量num。
         *
         *
         * 分析过程如下:
         * 考虑到线程的不确定性,因此我们不能确保ThreadA就一定先于ThreadB和ThreadC前执行,就算
         * ThreadA先执行了,我们也无法保证ThreadA什么时候才能将变量num初始化完成。因此我们必须让
         * ThreadB和ThreadC去等待ThreadA完成任务后发出的消息
         *
         * 解决两个问题:
         * 1:让ThreadB和ThreadC先执行完
         * 2:ThreadA执行完之后给ThreadB和ThreadC发送消息
         */
        /**
         * 两种解决方案
         * 1、使用纯Java API的Semaphore类来控制线程的等待和释放
         * 2、使用Android提供的消息机制
         */
    
        //定义一个变量作为数据
        private static int num;
    
        public static void main(String[] args) {
            Thread threadA = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        //模拟耗时操作之后初始化变量num
                        Thread.sleep(1000);
                        num=1;
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
            Thread threadB = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName()+"获取到num的值为:"+num);
                }
            });
            Thread threadC = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName()+"获取到num的值为:"+num);
                }
            });
            //同时开启三个线程
            threadA.start();
            threadB.start();
            threadC.start();
        }
    }
    

     运行结果:

    Thread-2获取到num的值为:0
    Thread-1获取到num的值为:0

    解决方案1:

      

    public class ThreadCommunication {
        /**
         * 三个线程a、b、c并发运行,b,c需要a线程的数据怎么实现
    public class ThreadCommunication {
    
        //定义一个变量作为数据
        private static int num;
        /**
         * 定义一个信号量,该类内部维持了多个线程锁,可以阻塞多个线程,释放多个线程
         * 线程的阻塞是和释放是通过permit概念来实现的
         * 线程通过semaphore.acquire()方法获取permit,如果当前线程有permit则分配给该线程
         * 如果没有则阻塞该线程直到semaphore
         * 调用release()方法释放permit
         * 构造函数中参数:permit(允许)个数;
         */
        private static Semaphore semaphore = new Semaphore(0);
    
        public static void main(String[] args) {
            Thread threadA = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        //模拟耗时操作之后初始化变量num
                        Thread.sleep(1000);
                        num = 1;
                        //初始化参数后释放两个permit
                        semaphore.release(2);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
            Thread threadB = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        //获取permit,如果semaphore没有可用的permit则等待,如果有则消耗一个
                        semaphore.acquire();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+"获取到的num的值为:"+num);
                }
            });
            Thread threadC = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        //获取permit,如果semaphore没有可用的permit则等待,如果有则消耗一个
                        semaphore.acquire();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+"获取到的num的值为:"+num);
                }
            });
            //同时开启三个线程
            threadA.start();
            threadB.start();
            threadC.start();
        }
    }

    运行结果:

    Thread-1获取到的num的值为:1
    Thread-2获取到的num的值为:1
  • 相关阅读:
    FPGA+ADV7511实现HDMI显示
    【转载】ZYNQ Cache问题的解决方法
    FPGA控制RGMII接口PHY芯片基础
    【转载】linux 压缩和解压缩命令gz、tar、zip、bz2
    python中正则表达式与模式匹配
    【转载】数字IC设计流程及开发工具
    Linux基本操作——文件相关
    数字信号处理专题(3)——FFT运算初探
    C++基础——类继承中方法重载
    C++基础——类继承
  • 原文地址:https://www.cnblogs.com/scar1et/p/11900641.html
Copyright © 2011-2022 走看看