题目:有三个线程分别打印A、B、C,请用多线程编程实现,在屏幕上循环打印10次ABCABC…
方法一:使用lock和condition来实现a执行完通知b执行,b执行完通知c执行,c执行完通知a执行的顺序,使用Executors的fixedthreadpool,将三个线程放到线程池里面,使用线程池控制程序的结束,调用shutdown()方法。
package com.ljf.thread.demo.lock;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Resources {
public static String threadName="A";//默认值为A;
public static Lock lock=new ReentrantLock();
public static Condition conA=lock.newCondition();
public static Condition conB=lock.newCondition();
public static Condition conC=lock.newCondition();
}
package com.ljf.thread.demo.lock;
public class ThreadA implements Runnable{
public void run() {
for(int k=0;k<10;k++){
Resources.lock.lock();
try {
while(!Resources.threadName.equals("A")){
try {
Resources.conA.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//打印信息
System.out.println(String.format("这是第%d遍执行",k+1));
System.out.println("A");
//唤醒b
Resources.threadName="B";
Resources.conB.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
Resources.lock.unlock();
}
}
}
}
package com.ljf.thread.demo.lock;
public class ThreadB implements Runnable {
public void run() {
for(int k=0;k<10;k++){
Resources.lock.lock();
try {
while(!Resources.threadName.equals("B")){
try {
Resources.conB.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//打印信息
System.out.println(String.format("这是第%d遍执行",k+1));
System.out.println("B");
//唤醒b
Resources.threadName="C";
Resources.conC.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
Resources.lock.unlock();
}
}
}
}
package com.ljf.thread.demo.lock;
public class ThreadC implements Runnable{
public void run() {
for(int k=0;k<10;k++){
Resources.lock.lock();
try {
while(!Resources.threadName.equals("C")){
try {
Resources.conC.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//打印信息
System.out.println(String.format("这是第%d遍执行",k+1));
System.out.println("C");
//唤醒b
Resources.threadName="A";
Resources.conA.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
Resources.lock.unlock();
}
}
}
}
package com.ljf.thread.demo.lock;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
public class TestABC {
public static void main(String args[]){
ExecutorService es= Executors.newFixedThreadPool(3);
es.execute(new ThreadA());
es.execute(new ThreadB());
es.execute(new ThreadC());
es.shutdown();
}
}
结果:
这是第1遍执行
A
这是第1遍执行
B
这是第1遍执行
C
这是第2遍执行
A
这是第2遍执行
B
这是第2遍执行
C
这是第3遍执行
A
这是第3遍执行
B
这是第3遍执行
C
这是第4遍执行
A
这是第4遍执行
B
这是第4遍执行
C
这是第5遍执行
A
这是第5遍执行
B
这是第5遍执行
C
这是第6遍执行
A
这是第6遍执行
B
这是第6遍执行
C
这是第7遍执行
A
这是第7遍执行
B
这是第7遍执行
C
这是第8遍执行
A
这是第8遍执行
B
这是第8遍执行
C
这是第9遍执行
A
这是第9遍执行
B
这是第9遍执行
C
这是第10遍执行
A
这是第10遍执行
B
这是第10遍执行
C
Process finished with exit code 0
https://mouselearnjava.iteye.com/blog/1949228
方法二:使用lock,通过公共统计次数来做判断实现顺序打印的,一个线程释放锁之后,自己和其他线程同时还会去抢夺公共锁,拿到锁且while里面的判读条件满足之后,才能打印。
package com.ljf.interview.thread;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock;
public class Resource {
public static int count=10;
public static int cnt=0;
public static ReentrantLock locks=new ReentrantLock();
}
package com.ljf.interview.thread;
public class PrintA implements Runnable{
@Override
public void run() {
for(int k=0;k<10;){
try {
Resource.locks.lock();
System.out.println("aaaa");
while (Resource.cnt % 3 == 0) {//多线程并发,不能用if,必须用循环测试等待条件,避免虚假唤醒
System.out.print("A");
Resource.cnt++;
k++;
}
} finally {
Resource.locks.unlock();// lock()和unlock()操作结合try/catch使用
}
}
}
}
package com.ljf.interview.thread;
public class PrintB implements Runnable {
@Override
public void run() {
for (int k = 0; k < 10; ) {
try {
Resource.locks.lock();
System.out.println("bbbb");
while (Resource.cnt % 3 == 1) {//多线程并发,不能用if,必须用循环测试等待条件,避免虚假唤醒
System.out.print("B");
Resource.cnt++;
k++;
}
} finally {
Resource.locks.unlock();// lock()和unlock()操作结合try/catch使用
}
}
}
}
package com.ljf.interview.thread;
import java.util.concurrent.locks.ReadWriteLock;
public class PrintC implements Runnable{
@Override
public void run() {
for(int k=0;k<10;){
try {
Resource.locks.lock();
System.out.println("ccc");
while (Resource.cnt % 3 == 2) {//多线程并发,不能用if,必须用循环测试等待条件,避免虚假唤醒
System.out.print("C");
Resource.cnt++;
k++;
}
} finally {
Resource.locks.unlock();// lock()和unlock()操作结合try/catch使用
}
}
}
}
package com.ljf.interview.thread;
public class PrintTask {
public static void main(String args[]){
new Thread(new PrintA(),"1").start();
new Thread(new PrintC(),"3").start();
new Thread(new PrintB(),"2").start();
}
}
结果:
ABCABCABCABCABCABCABCABCABCABC