多线程(字符串多线程交替输出的多种实现方式)

最近看到一道面试题字符串两个线程交替输出,简单写一下做个记录,先用到的就是wait和notify,初始代码如下:

package test.thread.wait; public class Wait1 {private String str1 = "ABCDEFGH"; private String str2 = "abcdef"; /** * 用于控制字符串长度不一致的flag */ private volatile boolean flag = false; public synchronized void m1() throws InterruptedException { int length = str1.length(); int i = 0; while (i < length) { System.out.println(str1.charAt(i)); if (!flag) { this.notify(); // 最后一个就不wait了,直接结束 if (i < length - 1) { this.wait(); } } if (i == length - 1) { flag = true; } i++; }}public synchronized void m2() throws InterruptedException { int length = str2.length(); int i = 0; while (i { try { wait1.m1(); } catch (InterruptedException e) { e.printStackTrace(); } }); Thread t2 = new Thread(() -> { try { wait1.m2(); } catch (InterruptedException e) { e.printStackTrace(); } }); t1.start(); t2.start(); }}


当然,也可以使用Lock的await,condition 或者LockSupport的park,unpark实现。
贴上代码 Lock的await,condition 的实现:
【多线程(字符串多线程交替输出的多种实现方式)】
import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; public class TestLock {private final ReentrantLock lock = new ReentrantLock(); private Condition condition1 = lock.newCondition(); private Condition condition2 = lock.newCondition(); private String str1 = "ABCDEFGH"; private String str2 = "abcdef"; /** * 用于控制字符串长度不一致的flag */ private volatile boolean flag = false; public void m1() throws InterruptedException { int length = str1.length(); int i = 0; while (i < length) { System.out.println(str1.charAt(i)); if (!flag) { try { lock.lock(); condition2.signal(); if (i < length - 1) { condition1.await(); } } finally { lock.unlock(); } } if (i == length - 1) { flag = true; } i++; } }public synchronized void m2() throws InterruptedException { int length = str2.length(); int i = 0; while (i < length) { System.out.println(str2.charAt(i)); if (!flag) { try { lock.lock(); condition1.signal(); if (i < length - 1) { condition2.await(); } } finally { lock.unlock(); } } if (i == length - 1) { flag = true; } i++; }}public static void main(String[] args) { TestLock testLock = new TestLock(); Thread t1 = new Thread(() -> { try { testLock.m1(); } catch (InterruptedException e) { e.printStackTrace(); } }); Thread t2 = new Thread(() -> { try { testLock.m2(); } catch (InterruptedException e) { e.printStackTrace(); } }); t1.start(); t2.start(); } }


LockSupport的park,unpark实现:

import java.util.concurrent.locks.LockSupport; public class LockSupport1 {private static String str1 = "ABCDEFGH"; private static String str2 = "abcdef"; /** * 用于控制字符串长度不一致的flag */ private volatile static boolean flag; private static Thread t1, t2; public static void m1() { int i = 0; int length = str1.length(); while (i < length) { System.out.println(str1.charAt(i)); LockSupport.unpark(t2); if (!flag) { if (i < length - 1) { LockSupport.park(); } } if (i == length - 1) { flag = true; } i++; } }public static void m2() { int i = 0; int length = str2.length(); while (i < length) { if (!flag) { // 最后一次时候还是要等待另外一个线程唤醒,否则会直接输出了 LockSupport.park(); } System.out.println(str2.charAt(i)); if (i == length - 1) { flag = true; } LockSupport.unpark(t1); i++; } }public static void main(String[] args) { t1 = new Thread(() -> { LockSupport1.m1(); }); t2 = new Thread(() -> { LockSupport1.m2(); }); t1.start(); t2.start(); }}


    推荐阅读