练习题

三个线程abc并发允许,bc需要a线程的数据怎么实现。

2020-07-11  本文已影响0人  老奶猹

根据问题的描述,我将问题用以下代码演示,ThreadA、ThreadB、ThreadC,ThreadA 用于初始化数据 num,
只有当num初始化完成之后再让ThreadB和ThreadC获取到初始化后的变量num。
分析过程如下:
考虑到多线程的不确定性,因此我们不能确保ThreadA就一定先于ThreadB和ThreadC前执行,就算ThreadA
先执行了,我们也无法保证ThreadA什么时候才能将变量num给初始化完成。因此我们必须让ThreadB和ThreadC
去等待ThreadA完成任何后发出的消息。
现在需要解决两个难题,一是让 ThreadB 和 ThreadC 等待 ThreadA 先执行完,二是 ThreadA 执行完之后给
ThreadB和ThreadC发送消息。
使用Java API的Semaphore类来控制线程的等待和释放

public class ThreadCommunication  {
    private static int num;
        /**
     * 定义一个信号量,该类内部维持了多个线程锁,可以阻塞多个线程,释放多个线程, 
. 线程的阻塞和释放是通过 permit 概念来实现的 
   * 线程通过 semaphore.acquire()方法获取 permit,如果当前 semaphore 有 permit 则分配给该线程,
 如果没有则阻塞该线程直到 semaphore 
  * 调用 release()方法释放 permit。 
   * 构造函数中参数:permit(允许) 个数
    */
    //声明一个semaphore对象
    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;
                    //释放2个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);

               }
        });
        //同时开启3个线程
        threadA.start();
        threadB.start();
        threadC.start();
    }
}
上一篇 下一篇

猜你喜欢

热点阅读