用两个线程交替打印数字和字母

前一段时间听马士兵老师讲课,讲到某公司的一个面试,两个线程,其中一个线程输出ABC,另一个线程输出123,如何控制两个线程交叉输出1A2B3C,由于本人多线程掌握的一直不是很好,所以听完这道题,个人感觉收获良多,这是一个学习笔记。这道题有多种解法,不过有些属于纯炫技,所以只记录常见的三种解法。首先看第一种 park 和 unpark package cn.bridgeli.demo; import com.google.common.collect.Lists; import java.util.List; import java.util.concurrent.locks.LockSupport; /** * @author BridgeLi * @date 2021/2/6 16:14 */ public class Thread_Communication_Park_Unpark { static Thread t1 = null; static Thread t2 = null; public static void main(String[] args) { final List<Integer> integers = Lists.newArrayList(1, 2, 3, 4, 5, 6, 7); final List<String> strings = Lists.newArrayList("A", "B", "C", "D", "E", "F", "G"); t1 = new Thread(() -> integers.forEach(item -> { System.out.print(item); LockSupport.unpark(t2); LockSupport.park(); }), "t1"); t2 = new Thread(() -> strings.forEach(item -> { LockSupport.park(); System.out.print(item); LockSupport.unpark(t1); }), "t2"); t1.start(); t2.start(); } } 这个是最简单的实现方法,LockSupport.park() 使当前线程阻塞,而 LockSupport.unpark() 则表示唤醒一个线程,所以他需要一个参数,表示你要唤醒哪个线程,很好理解,也比较简单。 ...

February 7, 2021 · 2 min · 413 words · Bridge Li

关于synchronized用法的简单理解

synchronized 关键字既可以用于声明方法,也可以用于声明代码块,他们之间有什么区别呢?下面让我们逐一测试一下。 先看以第一个例子: package demo; public class SynchronizedDemo1 { public synchronized static void foo1() { } public synchronized static void foo2() { } } 在这个例子中,foo1 和 foo2 是类的两个静态方法。在不同的线程中,这两个方法的调用时互斥的,不仅是他们之间,任何两个不同的线程的调用也互斥。下面看第二个例子: package demo; public class SynchronizedDemo2 { public synchronized void foo3() { } public synchronized void foo4() { } } 在这个例子中,foo3 和 foo4 是类的两个成员方法,在多线程环境中,调用同一个对象的 foo3 或者 foo4 是互斥的,与上一个例子的差别在于,这是针对同一个对象的多线程方法调用互斥。下面再看最后一个例子: package demo; public class SynchronizedDemo3 { public void foo5() { synchronized (this) { } } public void foo6() { synchronized (SynchronizedDemo3.class) { } } } 在这个例子中,synchronized 用来修饰代码块,需要注意的是:synchronized 后面会有一个参数,其实这个就是用于同步的锁所属的对象。在这个例子中 synchronized (this) 与 SynchronizedDemo2 中加 synchronized 的成员方法是互斥的,而 synchronized (SynchronizedDemo3.class) 与 SynchronizedDemo1 中加 synchronized 的静态方法是互斥的。synchronized 用于修饰代码块会更加灵活,因为除了前面的这个例子外,synchronized 后面的参数可以是任意对象。

May 14, 2017 · 1 min · 99 words · Bridge Li