龙空技术网

JAVA并发编程 | 两个线程交替打印两个数组中的元素

死牛胖子 238

前言:

此刻大家对“java打印心”大致比较着重,大家都想要知道一些“java打印心”的相关资讯。那么小编也在网摘上汇集了一些有关“java打印心””的相关资讯,希望同学们能喜欢,朋友们快快来了解一下吧!

有如下两个数组,开启两个线程,分别控制一个数组,每次输出一个字符,两个线程轮流输出。

数组一:1234567数组二:ABCDEFG输出结果:1A2B3C4D5E6F7G
有锁实现wait / notify

多线程编程最基本的方法,通过 wait/notify 方法进行线程间的交互,从而实现线程间轮流输出。

public class SynchronizedTest() {    public static void main(String[] args) {        char[] ai = "1234567".toCharArray();        char[] ac = "ABCDEFG".toCharArray();        Object obj = new Object();        Thread t1 = new Thread(() -> {            synchronized (obj) {                for (char c : ai) {                    System.out.print(c);                    try {                        obj.notify();  // 唤醒其它线程                        obj.wait();    // 阻塞 t1                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }                obj.notify();            }        });        Thread t2 = new Thread(() -> {            synchronized (obj) {                for (char c : ac) {                    System.out.print(c);                    try {                        obj.notify();  // 唤醒其它线程                        obj.wait();    // 阻塞 t2                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }                obj.notify();            }        });        t1.start();        t2.start();    }}
LockSupport

LockSupport 是一个线程阻塞工具类,可以让线程在任意位置阻塞或者唤醒。

方法介绍:

LockSupport.park(),阻塞当前线程LockSupport.park(线程名),阻塞指定线程LockSupport.unpark(线程名),唤醒指定线程

public class LockSupportTest {    private static Thread t1, t2;    public static void main(String[] args) {        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            }        });        t2 = new Thread(() -> {            for (char c : ac) {                LockSupport.park();      // 阻塞 t2                System.out.print(c);                LockSupport.unpark(t1);  // 唤醒 t1            }        });        t1.start();        t2.start();    }}
无锁实现volatile

利用 volatile 线程可见性的特性,当 displayFlagtrue 时,第一个线程输出,为 false 时,第二个线程输出,如此反复。

public class VolatileTest {    private static volatile boolean displayFlag = true;    public static void main(String[] args) {        char[] ai = "1234567".toCharArray();        char[] ac = "ABCDEFG".toCharArray();        Thread t1 = new Thread(() -> {            for (char c : ai) {                while (!displayFlag) {                }                System.out.print(c);                displayFlag = false;            }        });        Thread t2 = new Thread(() -> {            for (char c : ac) {                while (displayFlag) {                }                System.out.print(c);                displayFlag = true;            }        });        t1.start();        t2.start();    }}
Atomic 原子类

利用原子类中的方法具备原子性的特性

public class AtomicTest {    private static AtomicInteger atomicFlag = new AtomicInteger(0);    public static void main(String[] args) {        char[] ai = "1234567".toCharArray();        char[] ac = "ABCDEFG".toCharArray();        Thread t1 = new Thread(() -> {            for (char c : ai) {                while (atomicFlag.get() == 1) {                }                System.out.print(c);                atomicFlag.set(1);            }        });        Thread t2 = new Thread(() -> {            for (char c : ac) {                while (atomicFlag.get() == 0) {                }                System.out.print(c);                atomicFlag.set(0);            }        });        t1.start();        t2.start();    }    }

方法其实还有很多,有兴趣的同学可以自己动手,并在文章下面回复,共同学习。

接下来会陆续推出 JAVA并发编程、数据库、JVM、Spring、SpringBoot、SpringCloud的用法及源码分析,有兴趣的可以关注一下

标签: #java打印心