记训练营给师弟的第二道多线程训练
一、题目与要求
static class PrintOrdered {
private int n;
public PrintOrdered(int n) {
this.n = n;
}
public void one() throws InterruptedException {
for (int i = 0; i < n; i++) {
System.out.print("1");
}
}
public void two() throws InterruptedException {
for (int i = 0; i < n; i++) {
System.out.print("2");
}
}
}
public static void main(String[] args) throws InterruptedException{
PrintOrdered printOrdered=new PrintOrdered(100);
Runnable r1 = () -> {
try {
printOrdered.one();
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Runnable r2 = () -> {
try {
printOrdered.two();
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Thread t=new Thread(r1);
Thread t1=new Thread(r2);
Thread.sleep(100);
t.start();
t1.start();
}
二、解法一
static class PrintOrdered {
private int n;
private boolean flag;
public PrintOrdered(int n) {
this.n = n;
this.flag=true;
}
public void one() throws InterruptedException {
for (int i = 0; i < n; i++) {
while(flag!=true){
}
System.out.print("1");
flag=false;
}
}
public void two() throws InterruptedException {
for (int i = 0; i < n; i++) {
while(flag!=false){
}
System.out.print("2");
flag=true;
}
}
}
三、解法二
static class PrintOrdered {
private int n;
private BlockingQueue<Integer> oneQueue;
private BlockingQueue<Integer> twoQueue;
public PrintOrdered(int n) {
this.n = n;
twoQueue = new LinkedBlockingQueue<>();
ArrayList<Integer> arrayList = new ArrayList();
arrayList.add(0);
oneQueue = new LinkedBlockingQueue<>(arrayList);
}
public void one() throws InterruptedException {
for (int i = 0; i < n; i++) {
oneQueue.take();
System.out.print("1");
twoQueue.put(i);
}
}
public void two() throws InterruptedException {
for (int i = 0; i < n; i++) {
twoQueue.take();
System.out.print("2");
oneQueue.put(i);
}
}
}
四、解法三
static class PrintOrdered {
private int n;
private ReentrantLock lock = new ReentrantLock();
private Condition condition1 = lock.newCondition();
private Condition condition2 = lock.newCondition();
private int flag=0;
public PrintOrdered(int n) {
this.n = n;
}
public void one() throws InterruptedException {
for (int i = 0; i < n; i++) {
lock.lock();
try {
if (flag!=0){
condition1.await();
}
System.out.print("1");
flag++;
condition2.signal();
} finally {
lock.unlock();
}
}
}
public void two() throws InterruptedException {
for (int i = 0; i < n; i++) {
lock.lock();
try {
if (flag!=1){
condition2.await();
}
System.out.print("2");
flag--;
condition1.signal();
} finally {
lock.unlock();
}
}
}
}
public static void main(String[] args) throws InterruptedException{
PrintOrdered printOrdered=new PrintOrdered(100);
Runnable r1 = () -> {
try {
printOrdered.one();
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Runnable r2 = () -> {
try {
printOrdered.two();
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Thread t=new Thread(r1);
Thread t1=new Thread(r2);
Thread.sleep(100);
t.start();
t1.start();
}