一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第12天,点击查看活动详情。
字符交替打印
1.使用LockSupport
使用工具类LockSupport精准阻塞和唤醒线程 LockSupport.unpark() 唤醒 LockSupport.unpark() 阻塞 AQS就是使用这个工具类阻塞唤醒
public class LockSupport01 {
static Thread t1,t2;
public static void main(String[] args) {
char[] a = "abcdefg".toCharArray();
char[] b = "1234567".toCharArray();
t1 = new Thread(() -> {
for (char a1 : a) {
System.out.println(a1);
LockSupport.unpark(t2);
LockSupport.park();
}
}, "t1");
t2 = new Thread(()->{
for (char b1:b) {
LockSupport.park();
System.out.println(b1);
LockSupport.unpark(t1);
}
},"t2");
t1.start();
t2.start();
}
}
2.使用Synchronized
使用工具类Synchronized加锁 notify 唤醒 wait 阻塞
public class Synchronized02 {
public static void main(String[] args) {
Object o = new Object();
char[] a = "abcdefg".toCharArray();
char[] b = "1234567".toCharArray();
new Thread(() -> {
synchronized (o){
for (char a1 : a) {
try {
System.out.println(a1);
o.notify();
o.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
o.notify(); //加这个是在结束的时候在唤醒一下其他线程,以免其他线程在阻塞状态
}
}, "t1").start();
new Thread(()->{
synchronized (o){
for (char b1:b) {
System.out.println(b1);
o.notify();
try {
o.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
o.notify();
}
},"t2").start();
}
}
3.使用CountDownLatch控制先后顺序
使用CountDownLatch 可以实现先打印小a 或者数字1 控制开始顺序
public class CountDownLatch03 {
//使用countDownLatch 控制线程执行先后顺序
private static CountDownLatch countDownLatch =new CountDownLatch(1);
public static void main(String[] args) {
Object o = new Object();
char[] a = "abcdefg".toCharArray();
char[] b = "1234567".toCharArray();
new Thread(() -> {
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (o){
for (char a1 : a) {
System.out.println(a1);
o.notify();
try {
o.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
o.notify();
}, "t1").start();
new Thread(()->{
synchronized (o){
for (char b1:b) {
countDownLatch.countDown();
System.out.println(b1);
o.notify();
try {
o.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
o.notify();
}
},"t2").start();
}
}
4.使用ReentrantLock
使用ReentrantLock 可以实现两个以上的交替打印 Synchronized只能实现两个 Condition 的等待和唤醒
public class ReentrantLock04 {
//使用countDownLatch 控制线程执行先后顺序
private static ReentrantLock reentrantLock =new ReentrantLock();
public static void main(String[] args) {
Condition condition =reentrantLock.newCondition();
Condition condition2 =reentrantLock.newCondition();
Condition condition3 =reentrantLock.newCondition();
Object o = new Object();
char[] a = "abcdefg".toCharArray();
char[] b = "1234567".toCharArray();
char[] c = "ABCDEFG".toCharArray();
new Thread(() -> {
reentrantLock.lock();
try {
for (char a1 : a) {
System.out.println(a1);
condition2.signal();
condition.await();
}
condition2.signal();
}catch (InterruptedException e) {
e.printStackTrace();
}finally {
reentrantLock.unlock(); //不释放锁线程会一直存在
}
}, "t1").start();
new Thread(()->{
reentrantLock.lock();
try {
for (char b1:b) {
System.out.println(b1);
condition3.signal();
condition2.await();
}
condition3.signal();
}catch (InterruptedException e) {
e.printStackTrace();
}finally {
reentrantLock.unlock(); //不释放锁线程会一直存在
}
},"t2").start();
new Thread(()->{
reentrantLock.lock();
try {
for (char c1:c) {
System.out.println(c1);
condition.signal();
condition3.await();
}
condition.signal();
}catch (InterruptedException e) {
e.printStackTrace();
}finally {
reentrantLock.unlock(); //不释放锁线程会一直存在
}
},"t3").start();
}
}