编写一段代码,创建2个线程,一个线程循环输出123...90123...,另一个线程循环输出ABC...ZABC...,要求控制台最终输出效果为1A2B3C4D5E...。
方案1:
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class NumberCharTest {
public static void main(String[] args) {
NumberChar numberChar = new NumberChar();
new Thread(() -> {
numberChar.printNumber();
}, "数字").start();
new Thread(() -> {
numberChar.printChar();
}, "字符").start();
}
}
class NumberChar {
private int startNum = 1;
private char startChar = 'A';
private ReentrantLock lock = new ReentrantLock();
Condition numCondition = lock.newCondition();
Condition charCondition = lock.newCondition();
public void printNumber() {
while (true) {
try {
lock.lock();
TimeUnit.SECONDS.sleep(1);
System.out.println(Thread.currentThread().getName() + ":" + startNum++);
charCondition.signal();
numCondition.await();
if (startNum == 10) {
startNum = 0;
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
public void printChar() {
while (true) {
try {
lock.lock();
TimeUnit.SECONDS.sleep(1);
System.out.println(Thread.currentThread().getName() + ":" + startChar++);
numCondition.signal();
charCondition.await()
if (startChar == 'Z' + 1) {
startChar = 'A';
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}
方案2:
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class NumberCharTest2 {
public static void main(String[] args) {
List arr = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 0);
List arr2 = Arrays.asList('A', 'B', 'C', 'D', 'E', 'F', 'G');
ReentrantLock reentrantLock = new ReentrantLock();
Condition condition1 = reentrantLock.newCondition();
Condition condition2 = reentrantLock.newCondition();
Condition condition3 = reentrantLock.newCondition();
Task task = new Task(arr, reentrantLock, condition1, condition2);
Task task2 = new Task(arr2, reentrantLock, condition2, condition1);
Thread t1 = new Thread(task, "线程1");
Thread t2 = new Thread(task2, "线程2");
t1.start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
t2.start();
}
}
class Task implements Runnable {
private List objs;
private ReentrantLock reentrantLock;
private Condition currentCondition;
private Condition otherCondition;
public Task(List objs, ReentrantLock reentrantLock, Condition currentCondition, Condition otherCondition) {
this.objs = objs;
this.reentrantLock = reentrantLock;
this.currentCondition = currentCondition;
this.otherCondition = otherCondition;
}
@Override
public void run() {
while (true) {
reentrantLock.lock();
for (int i = 0; i < objs.size(); i++) {
System.out.println(Thread.currentThread().getName() + "输出:" + objs.get(i));
try {
otherCondition.signal();
currentCondition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
reentrantLock.unlock();
}
}
}
}
2种方案总结
其实这2种方案都差不多,第一种更加清晰一点,第二种便于控制,灵活一点,能够很方便的再加一个新的线程进来进行相应的操作。