【并发编程】多个线程交替输出的经典例题:wait/notify、await/signal 、park/unpark

package ConcurrentDemo;

//经典并发题:利用三个线程交替输出abcabcabcabc

import org.junit.Test;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReentrantLock;

/*
解题技巧:
1.利用等待/通知 wait/notify
2.await/signal
3.park/unpark
*/
public class ABCAlternateDemo {
    public static void main(String[] args) {

    }
    @Test
    public void waitAndNotifyTest(){
        Message message=new Message(1,4);
        new Thread(()-> {
            message.print("a",1,2);

        },"t1").start();
        new Thread(()-> {
            message.print("b",2,3);

        },"t2").start();
        new Thread(()-> {
            message.print("c",3,1);

        },"t3").start();
    }
    @Test
    public void awaitAndSignalTest() throws InterruptedException {
       AwaitSignal aw=new AwaitSignal(4);
       Condition con1=aw.newCondition();
       Condition con2=aw.newCondition();
       Condition con3=aw.newCondition();
        new Thread(()-> {
           aw.print("a",con1,con2);
        },"t1").start();
        new Thread(()-> {
           aw.print("b",con2,con3);
        },"t2").start();
        new Thread(()-> {
            aw.print("c",con3,con1);
        },"t3").start();

        TimeUnit.SECONDS.sleep(1);
        aw.lock();
        try {
            con1.signal();//主线程唤醒线程1
        }finally {
            aw.unlock();
        }

    }

    static  Thread t1,t2,t3;
    @Test
    public void parkAndUparkTest(){
        ParkAndUnpark pau=new ParkAndUnpark(4);
        t1= new Thread(()-> { pau.print("a",t2);},"t1");
        t2=  new Thread(()-> {pau.print("b",t3);},"t2");
       t3=new Thread(()-> { pau.print("c",t1); },"t3");
        t1.start();
        t2.start();
        t3.start();
        LockSupport.unpark(t1);//主线程唤醒线程1
    }
}
class Message{
  private int flag;
  private int loopNumber;
    public Message(int flag, int loopNumber) {
        this.flag = flag;
        this.loopNumber = loopNumber;
    }

    public void print(String word, int startFlag, int endFlag){
        for (int i=0; i<loopNumber ;i++) {
            synchronized (this) {
                while (flag != startFlag) {
                    try {
                        this.wait();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                System.out.print(word);
                flag = endFlag;
                this.notifyAll();
            }
        }
  }
 }
 class AwaitSignal extends ReentrantLock{
     private int loopNumber;
     public AwaitSignal(int loopNumber){
         this.loopNumber = loopNumber;
     }
     public void print(String word, Condition waitRoom, Condition signalRoom){
         //这种方案不能避免虚假唤醒,只是当前程序只有三个打印线程
         for (int i=0; i<loopNumber ;i++) {
             lock();
             try{
             //所有线程一开始就进入对应等待室,等待被唤醒
                 waitRoom.await();
                 System.out.print(word);
                 signalRoom.signalAll();
             } catch (InterruptedException e) {
                 e.printStackTrace();
             } finally {
                 unlock();
             }
         }
     }
}
class ParkAndUnpark{
    private int loopNumber;
    public ParkAndUnpark(int loopNumber){
        this.loopNumber = loopNumber;
    }
    public void print(String word, Thread thread){
        for (int i=0; i<loopNumber ;i++) {
            LockSupport.park();
            System.out.print(word);
            LockSupport.unpark(thread);
        }
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值