这道题目在多线程的面试题中可能遇到的比较多,由于最近一直在学习Java多线程编程的知识,这里做一个总结,总结的可能并不是很全面,有问题或者有更好的编程方法也欢迎大家指出。
这道题目的实现方式很多,这里就以我了解的进行一个总结。
首先,我们看一下题目:
有三个线程A、B、C,采用多线程的方式使三个线程轮流执行顺序打印ABC 10次,结果如下:
package test.printThread.test2;
/**
*
* Title: PrintABCUsingWaitNotify.java
* Description:
* ABCABCABCABCABCABCABCABCABCABC
*
* @author tianqb
* @mail [email protected]
* @date 2019年6月7日下午5:29:39
* @version 1.0
*
*/
public class PrintABCUsingWaitNotify {
private int times;// 打印的次数
private int state = 0;// 打印的状态
private Object objectA = new Object();
private Object objectB = new Object();
private Object objectC = new Object();
public PrintABCUsingWaitNotify(int times) {
super();
this.times = times;
}
public void printA(){
print("A", 0, objectA, objectB);
}
public void printB(){
print("B", 1, objectB, objectC);
}
public void printC(){
print("C", 2, objectC, objectA);
}
public void print(String name, int targetState, Object curr, Object next){
for (int i = 0; i < times;) {
synchronized (curr) {
while(state % 3 != targetState){
try {
curr.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
i++;
state++;
System.out.print(name);
synchronized (next) {
next.notify();
}
}
}
}
public static void main(String[] args) {
PrintABCUsingWaitNotify p = new PrintABCUsingWaitNotify(10);
new Thread(new Runnable() {
@Override
public void run() {
p.printA();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
p.printB();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
p.printC();
}
}).start();
}
}
这里对题目进行一个扩展,顺序执行打印AAAAAAAAAABBBBBBBBBBCCCCCCCCCC
package test.printThread.test3;
/**
*
*
* Title: PrintABCUsingWaitNotify.java
*
*
* Description:
* AAAAAAAAAABBBBBBBBBBCCCCCCCCCC
*
*
* @author tianqb
* @mail [email protected]
* @date 2019年6月7日下午5:29:58
* @version 1.0
*
*/
public class PrintABCUsingWaitNotify {
private int times;// 打印的次数
private int state = 0;// 打印的状态
private Object objectA = new Object();
private Object objectB = new Object();
private Object objectC = new Object();
public PrintABCUsingWaitNotify(int times) {
super();
this.times = times;
}
public void printA() {
print("A", 0, objectA, objectB);
}
public void printB() {
print("B", 1, objectB, objectC);
}
public void printC() {
print("C", 2, objectC, objectA);
}
public void print(String name, int targetState, Object curr, Object next) {
synchronized (curr) {
while (state % 3 != targetState) {
try {
curr.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
state++;
for (int i = 0; i < times; i++) {
System.out.print(name);
}
synchronized (next) {
next.notify();
}
}
}
public static void main(String[] args) {
PrintABCUsingWaitNotify p = new PrintABCUsingWaitNotify(10);
new Thread(new Runnable() {
@Override
public void run() {
p.printC();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
p.printB();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
p.printA();
}
}).start();
}
}
public synchronized void start() {
/**
* This method is not invoked for the main method thread or "system"
* group threads created/set up by the VM. Any new functionality added
* to this method in the future may have to also be added to the VM.
*
* A zero status value corresponds to state "NEW".
*/
if (threadStatus != 0)
throw new IllegalThreadStateException();
/* Notify the group that this thread is about to be started
* so that it can be added to the group's list of threads
* and the group's unstarted count can be decremented. */
group.add(this);
boolean started = false;
try {
start0();
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
/* do nothing. If start0 threw a Throwable then
it will be passed up the call stack */
}
}
}
实现代码:
package test.printThread.test4;
public class PrintABCUsingJoin {
public static void main(String[] args) {
Thread a = new Thread(new Runnable() {
@Override
public void run() {
System.out.print("A");
}
});
Thread b = new Thread(new Runnable() {
@Override
public void run() {
try {
a.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print("B");
}
});
Thread c = new Thread(new Runnable() {
@Override
public void run() {
try {
b.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print("C");
}
});
for (int i = 0; i < 10; i++) {
a.run();
b.run();
c.run();
}
}
}
package test.printThread.test5;
public class PrintABCUsingIsAlive {
public static void main(String[] args) throws InterruptedException {
Thread A = new Thread(() -> {
System.out.print("A");
});
Thread B = new Thread(() -> {
System.out.print("B");
});
Thread C = new Thread(() -> {
System.out.print("C");
});
int i = 10;
while (i > 0) {
A.run();
while (A.isAlive()) {
}
B.run();
while (B.isAlive()) {
}
C.run();
while (C.isAlive()) {
}
i--;
}
}
}
package chapter4.locks.printABC;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class PrintABC {
private int times;
private int count = 0;
private Lock lock = new ReentrantLock();
private Condition c1 = lock.newCondition();
private Condition c2 = lock.newCondition();
private Condition c3 = lock.newCondition();
public PrintABC(int times) {
super();
this.times = times;
}
public void print(int target, Condition curr, Condition next){
for (int i = 0; i < times;) {
try {
lock.lock();
while(count % 3 != target){
curr.await();
}
System.out.print(Thread.currentThread().getName());
count++;
i++;
next.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
public void printA(){
print(0, c1, c2);
};
public void printB(){
print(1, c2, c3);
};
public void printC(){
print(2, c3, c1);
};
}
package chapter4.locks.printABC;
public class Run {
public static void main(String[] args) {
PrintABC p = new PrintABC(10);
new Thread(() -> {
p.printA();
},"A").start();
new Thread(() -> {
p.printB();
},"B").start();
new Thread(() -> {
p.printC();
},"C").start();
}
}
目前了解的就这么些了,之后学习到新的方法继续更新。