多线程交替输出abc100次(wait/notify)

先上代码:

public class Printer {

    public static void main(String[] args) {
        start();
    }

    private static int flg = 1;

    private static final Object lock = new Object();

    //控制打印次数
    private static int num = 0;

    private static void start() {
        Thread t1 = new Thread(() -> {
            while (num < 100) {
                synchronized (lock) {
                    if (flg == 1) {
                        System.out.print("a");
                        flg = 2;
                        lock.notifyAll();
                    } else {
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }
            }
        }, "t1");

        Thread t2 = new Thread(() -> {
            while (num < 100) {
                synchronized (lock) {
                    if (flg == 2) {
                        System.out.print("b");
                        flg = 3;
                        lock.notifyAll();
                    } else {
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }
            }
        }, "t2");

        Thread t3 = new Thread(() -> {
            while (num < 100) {
                synchronized (lock) {
                    if (flg == 3) {
                        System.out.print("c");
                        num++;
                        flg = 1;
                        lock.notifyAll();
                    } else {
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }
            }
        }, "t3");
        t1.start();
        t2.start();
        t3.start();
    }
}

          首先,来一把对象锁 lock,static是在类加载是为了保证锁对象只加载1次,final是为了防止锁引用的对象中间被修改造成并发问题。

          然后是start方法,在这里创建3个线程,并启动,直接被main调用,也设为static。

          接下来是设置flag信号,表示当前该输出的数字。

          那么我们接下来就需要实现Runnable接口了,使用Lambda表达式,首先不考虑计数,我们可以先设为无限循环while(true),然后抢锁,抢到之后,如果发现flag不对,就调wait释放锁,此线程就阻塞在wait那里,直到下次它再被唤醒,才会进入下一轮循环继续抢对象锁。那flag对上了的话,就可以输出了,注意要将flag调成下一个,在最后调下notifyAll唤醒所有monitor等待队列中wait的线程。

         设为while(true)是因为循环是不断重试的,有可能抢到锁但本轮并不应该是它输出,所以用了无限循环,这样也会一直交替打印下去,那我们怎么控制器打印次数呢?为此我引入了计数器,打完c之后加一,最后计数器的值小于一个固定值即可!大于就跳出while循环,循环执行结束!注意不能用for循环100次,因为中间的一次循环进入后并不一定flag正确,即并不应该当前线程进行打印!

        大家对我这种写法怎么看,欢迎交流呀!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值