多线程交叉打印

问题:多线程交叉打印

典型的生产者消费者模型

初步代码:

class T implements Runnable{
    Object o = new Object();
    boolean flag = false;

    @Override
    public void run() {
        String s = Thread.currentThread().getName();
        if (s.equals("A")) {
            while(true){ // 保障线程一直走
                System.out.println("1");
                synchronized (o){
                    while(flag){ // 用while(条件)来确保notifyAll即使抢到优先权了不满足条件也给我等待。
                        System.out.println("11");
                        try{
                            o.wait();
                        }catch (Exception e){
                            e.printStackTrace();
                        }
                    }
                    System.out.println("thread-a");
                    flag = true;
                    o.notifyAll(); // 当某个线程调用notifyAll方法后,虽然其他线程被唤醒了,但是该线程依然持有着对象锁,
                    // 必须等该同步代码块执行完(右大括号结束)后才算正式释放了锁对象,另外线程才有机会执行
                }
            }
        } else {
            while(true){
                System.out.println("2");
                synchronized (o){
                    while(!flag){
                        System.out.println("22");
                        try{
                            o.wait();
                        }catch (Exception e){
                            e.printStackTrace();
                        }
                    }
                    System.out.println("thread-b");
                    flag = false;
                    o.notifyAll();
                }
            }
        }
    }
    // wait 是对象的锁,释放了锁对象,用notify/notifyAll唤醒,通常用while(!condition){this.wait();}限制不该唤醒的线程(notify只是随机唤醒);
    // sleep 是线程的休眠 不会释放锁对象,因为如果别人在休眠状态拿了锁,那就没意义了。
    public static void main(String[] args) {
        T t = new T();
        Thread t1 = new Thread(t, "A");
        Thread t2 = new Thread(t, "B");
        t1.start();
        t2.start();
    }
}

以下是某次结果:

1 //a线程首先开启
thread-a //获取锁对象,不满足while条件,打印
1 //notifyAll没用到;A线程继续循环打印
11 //满足while条件,打印后A等待,释放锁对象
2 //B线程终于启动了
thread-b //拿到锁对象,不满足while,打印
2 //打印
thread-a //notifyAll唤醒A后,与B争锁,A赢,不满足while,打印(及时B赢不满足条件还得等待)
1 //打印
thread-b //B争取了锁,不满足while条件,打印
2
thread-a
1
11
thread-b
2
thread-a
1
thread-b

事实上这段代码notifyAll换成notify也没问题,参加博客Java中notify和notifyAll的区别 - 何时以及如何使用
sleep()和wait()的区别及wait方法的一点注意事项
参考资料
参考资料
接下来是写法升级,未完待续。。。

发布了47 篇原创文章 · 获赞 21 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/qq_28929579/article/details/104736948