題目
交替打印A1b2c3……
用Locksupport解決
package com.inspire.juc.c_026_00_interview.A1B2C3;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.LockSupport;
public class T2_00_LockSupport {
static Thread t1=null,t2=null;
public static void main(String[] args) {
char[] aI="1234567".toCharArray();
char[] aC="ABCDEFG".toCharArray();
t1=new Thread(()->{
for(char c:aI){
System.out.println(c);
LockSupport.unpark(t2);//喚醒t2
LockSupport.park();//阻塞t1
}
},"t1");
t2=new Thread(()->{
for(char c:aC){
LockSupport.park();//阻塞t2
System.out.println(c);
LockSupport.unpark(t1);//喚醒t1
}
},"t2");
t1.start();
t2.start();
}
}
用synchronized、wait、notify解決
package com.inspire.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="123456".toCharArray();
char[] aC="ABCDEF".toCharArray();
new Thread(()->{
synchronized (o){
for(char i:aI){
System.out.println(i);
try {
o.notify();//喚醒t2
o.wait();//阻塞t1
} catch (InterruptedException e) {
e.printStackTrace();
}
}
o.notify();//喚醒t1
}
},"t1").start();
new Thread(()->{
synchronized (o){
for(char i:aC){
System.out.println(i);
try {
o.notify();//喚醒t1
o.wait();//阻塞t2
} catch (InterruptedException e) {
e.printStackTrace();
}
}
o.notify();//喚醒t2
}
},"t2").start();
}
}
新的要求:先輸出字母,再輸出數字
package com.inspire.juc.c_026_00_interview.A1B2C3;
public class T07_00_sync_wait_notify {
private static volatile boolean t2start=false;
public static void main(String[] args) {
final Object o=new Object();
char[] aI="123456".toCharArray();
char[] aC="ABCDEF".toCharArray();
new Thread(()->{
synchronized (o){
if(!t2start){//t2爲false時,t1等待
try {
o.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for(char c:aI){
System.out.println(c);
try {
o.notify();//喚醒t2
o.wait();//阻塞t1
} catch (InterruptedException e) {
e.printStackTrace();
}
}
o.notify();
}
},"t1").start();
new Thread(()->{
synchronized (o){
for(char c:aC){
System.out.println(c);
t2start=true;
try {
o.notify();//喚醒t1
o.wait();//阻塞t2
} catch (InterruptedException e) {
e.printStackTrace();
}
}
o.notify();
}
},"t2").start();
}
}
用一個condition來解決
package com.inspire.juc.c_026_00_interview.A1B2C3;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class T08_00_lock_condition {
public static void main(String[] args) {
Lock lock=new ReentrantLock();
Condition condition=lock.newCondition();
char[] aI="123456".toCharArray();
char[] aC="ABCDEF".toCharArray();
new Thread(()->{
try {
lock.lock();
for(char c:aI){
System.out.println(c);
condition.signal();//喚醒t2
condition.await();//阻塞t1
}
condition.signal();//這一步很重要,記得喚醒t2
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
},"t1").start();
new Thread(()->{
try {
lock.lock();
for(char c:aC){
System.out.println(c);
condition.signal();//喚醒t1
condition.await();//阻塞t2
}
condition.signal();//記得喚醒t1
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
},"t2").start();
}
}
用兩個condition來解決(和上一個比,更推薦這個)
package com.inspire.juc.c_026_00_interview.A1B2C3;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class T09_00_lock_condition {
public static void main(String[] args) {
char[] aI="123456".toCharArray();
char[] aC="ABCDEF".toCharArray();
Lock lock=new ReentrantLock();
Condition T1Condition=lock.newCondition();
Condition T2Condition=lock.newCondition();
new Thread(()->{
try {
lock.lock();
for(char c:aI){
System.out.println(c);
T2Condition.signal();
T1Condition.await();
}
T2Condition.signal();
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
},"t1").start();
new Thread(()->{
try {
lock.lock();
for(char c:aC){
System.out.println(c);
T1Condition.signal();
T2Condition.await();
}
T1Condition.signal();
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
},"t2").start();
}
}
注意
condition的語法是
不使用鎖來實現
package com.inspire.juc.c_026_00_interview.A1B2C3;
public class T03_00_cas {
enum ReadyToRun {T1, T2}
static volatile ReadyToRun r = ReadyToRun.T1;
public static void main(String[] args) {
char[] aI = "123456".toCharArray();
char[] aC = "ABCDEF".toCharArray();
new Thread(() -> {
for (char c : aI) {
while (r == ReadyToRun.T2) {
}
System.out.println(c);
r = ReadyToRun.T2;
}
}, "t1").start();
new Thread(() -> {
for (char c : aC) {
while (r == ReadyToRun.T1) {
}
System.out.println(c);
r = ReadyToRun.T1;
}
}, "t2").start();
}
}
使用BlockingQueue來解決
package com.inspire.juc.c_026_00_interview.A1B2C3;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class T04_00_BlockingQueue {
static BlockingQueue<String> q1=new ArrayBlockingQueue<>(1);
static BlockingQueue<String> q2=new ArrayBlockingQueue<>(1);
public static void main(String[] args) {
char[] aI="123456".toCharArray();
char[] aC="ABCDEF".toCharArray();
new Thread(()->{
for(char c:aI){
System.out.println(c);
try {
q1.put("ok");//阻塞當前線程
q2.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"t1").start();
new Thread(()->{
for(char c:aC){
try {
q1.take();//獲取q1,使得q1不再阻塞,進而執行t1中的q2.take;從而t2不再阻塞,相當於給t2開鎖
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(c);
try {
q2.put("ok");//阻塞當前線程
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"t2").start();
}
}
用TransferQueue來解決
TransferQueue:transfer一個數據,等待另一個線程來拿,拿完,隊列才能添加下一個數據,一般用於:等待一個結果,有了結果才能進行下一步,如面對面付款
package com.inspire.juc.c_026_00_interview.A1B2C3;
import java.util.concurrent.LinkedTransferQueue;
import java.util.concurrent.TransferQueue;
public class T13_TransferQueue {
public static void main(String[] args) {
char[] aI="123456".toCharArray();
char[] aC="ABCDEF".toCharArray();
TransferQueue<Character> queue=new LinkedTransferQueue<>();
new Thread(()->{
for(char c:aI){
try {
System.out.println(queue.take());//1.等待接收 3.從queue取得c,並打印輸出
queue.transfer(c);//4.將c添加進queue
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"t1").start();
new Thread(()->{
for(char c:aC){
try {
queue.transfer(c);//2.將c放進queue,等待接收 //6.將c放進queue,等待接收,循環往復
System.out.println(queue.take());//5.從queue取得c,並打印輸出
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"t2").start();
}
}