亲宝软件园·资讯

展开

Java 交替输出

小成同学_ 人气:0

交替输出问题

image-20211015145725097

一定要保证交替输出,这就涉及到两个线程的同步问题。

有人可能会想到,用睡眠时间差来实现,但是只要是多线程里面,线程同步玩sleep()函数的,99.99%都是错的。

这道题其实有100多种解法。

最简单的解法

是这个问题的最优解,但其实不是面试官想听到的答案

关键函数

Locksupport.park():阻塞当前线程
Locksupport.unpark(""):唤醒某个线程

LockSupport

package com.mashibing.juc.c_026_00_interview.A1B2C3
    
import java.util.concurrent.locks.LockSupport;

public class T02_00_LockSupport {
    
    static Thread t1 = null, t2 = null;
    
    public static void main(String[] args) throws Exception {
        char[] aI = "1234567".toCharArray();
        char[] aC = "ABCDEFG".toCharArray();
    
        t1 = new Thread(() -> {

                for (char c : aI) {
                    System.out.print(c);
                    LockSupport.unpark(t2); // 叫醒t2
                    LockSupport.park(); // t1阻塞 当前线程阻塞
                }

            }, "t1");

            t2 = new Thread(() -> {

                for (char c : aC) {
                    LockSupport.park(); // t2挂起
                    System.out.print(c);
                    LockSupport.unpark(t1); // 叫醒t1
                }

            }, "t2");

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

在这里插入图片描述

执行程序:

image-20211227162406095

是我们想要的结果。

面试官想听到的解法

synchronized wait notify

package com.mashibing.juc.c_026_00_interview.A1B2C3

public class T06_00_sync_wait_notify {
    
    public static void main(String[] args) {

        final Object o = new Object();

        char[] aI = "1234567".toCharArray();
        char[] aC = "ABCDEFG".toCharArray();

        new Thread(() -> {
            // 首先创建一把锁
            synchronized (o) {
                for (char c : aI) {
                    System.out.print(c);
                    try {
                        o.notify(); // 叫醒等待队列里面的一个线程,对本程序来说就是另一个线程
                        o.wait(); // 让出锁
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                o.notify(); // 必须,否则无法停止程序
            }
        }, "t1").start();

        new Thread(() -> {
            synchronized (o) {
                for (char c : aC) {
                    System.out.print(c);
                    try {
                        o.notify();
                        o.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                o.notify();
            }
        }, "t2").start();
    }
}

可能有人会想,代码中的notify()wait()顺序是不是没什么区别呢?那你就大错特错了,说明你不明白notify()wait()是怎么执行的。

这道题其实是华为面试的填空题,让你填notify()wait()

image-20211227192836696

如果我们先执行wait(),会先让自己直接进入等待队列,自己和另一个线程都在等待队列中等待,两个线程大

加载全部内容

相关教程
猜你喜欢
用户评论