多个线程以固定顺序运行-Java


当有多个线程需要start时,这时它们的运行顺序是不一定的,虽然如果你在主线程里假如是t1.start();t2.start();,可能大多数情况是t1先运行,但是也有可能是t2先运行。

两个线程

通过有一个布尔的Boolean runflag 来标记谁先运行

wait()/notifyAll()实现

实现先让t2先运行然后在t1

public class Test_has {
    static private byte lock[]=new byte[0];
    static private Boolean runflag=false;
    public static void main(String[] args) {
        Thread t1=new Thread(()->{
            synchronized (lock){
                while (!runflag){//runflag为false那么说明是t1先获得的锁,所以让它wait释放锁
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("t1运行");
            }
        },"t1");

        Thread t2=new Thread(()->{
            synchronized (lock){
                lock.notifyAll();
                runflag=true;
                System.out.println("t2运行");
            }
        },"t2");

        t1.start();
        t2.start();

    }
}

await()/signalAll()实现

public class Test_has {
    static private ReentrantLock lock=new ReentrantLock();
    static private Boolean runflag=false;

    public static void main(String[] args) {
        Condition condition = lock.newCondition();
        Thread t1=new Thread(()->{
            lock.lock();
            try{
                while (!runflag){//runflag为false那么说明是t1先获得的锁,所以让它wait释放锁
                    try {
                        condition.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("t1运行");
            }finally {
                lock.unlock();
            }

        },"t1");

        Thread t2=new Thread(()->{
            lock.lock();
            try {
                condition.signalAll();
                runflag=true;
                System.out.println("t2运行");
            }finally {
                lock.unlock();
            }
        },"t2");

        t1.start();
        t2.start();

    }
}

在这里插入图片描述

多个线程

wait()/notifyAll()实现

通过int类型的runflag来标记运行线程的次序
三个线程按照t2->t3->t1的顺序运
线程 运行标记 下一个运行标记
t1 1 2
t2 2 3
t3 3 1

public class Test_has {
    public static void main(String[] args) {
        Wait_Notify waitNotify=new Wait_Notify(2);
        new Thread(()->{
            waitNotify.print("我是t1",1,2);
        },"t1").start();
        new Thread(()->{
            waitNotify.print("我是t2",2,3);
        },"t2").start();
        new Thread(()->{
            waitNotify.print("我是t3",3,1);
        },"t3").start();
    }
}

class Wait_Notify{
   private int runflag;//标志当前可运行的标记

    public Wait_Notify(int runflag) {//第一次从哪个线程开始
        this.runflag = runflag;
    }

    public void print(String str, int myrunflag, int nextrunflag){
       for (int i = 0; i <10; i++) {
           synchronized (this){
               while (runflag!=myrunflag){//当前线程运行的标记不是可运行的标记
                   try {
                       this.wait();
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
               }
               //当前标记等于当前线程可以运行的标记则运行
               System.out.println(str);
               runflag=nextrunflag;
               this.notifyAll();
           }
       }
   }
}

在这里插入图片描述

await()/signalAll()实现

通过ReentrantLock条件变量的特性,不同的线程可以进入不同的等待队列等待。主线程开始唤醒第一个等待队列里的线程,所有线程开始都进入到各自的等待队列进行等待直到其他线程唤醒。

public class Test_has {
    public static void main(String[] args) throws InterruptedException {
        AwaitSignal awaitSignal=new AwaitSignal();
        Condition t1_condition = awaitSignal.newCondition();
        Condition t2_condition = awaitSignal.newCondition();
        Condition t3_condition = awaitSignal.newCondition();
        new Thread(()->{
            awaitSignal.print("我是t1",t1_condition,t3_condition);
        },"t1").start();
        new Thread(()->{
            awaitSignal.print("我是t2",t2_condition,t1_condition);
        },"t2").start();
        new Thread(()->{
            awaitSignal.print("我是t3",t3_condition,t2_condition);
        },"t3").start();
        Thread.sleep(100);
        awaitSignal.lock();
        t2_condition.signalAll();
        awaitSignal.unlock();
    }
}

class AwaitSignal extends ReentrantLock{
    public void print(String str,Condition nowcon,Condition nextcon){
        for (int i = 0; i <5; i++) {
            this.lock();
            try{
                nowcon.await();
                System.out.println(str);
                nextcon.signalAll();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                this.unlock();
            }
        }

    }
}

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值