线程1打印A1 A2 A3。线程2打印B1 B2 B3。我想编写一个程序,确保两个线程运行输出时都是A1 B1 A2 B2 A3 B3。到目前为止,我已经提出了以下计划。请告诉我这是如何简化的? 我们可以使用更少的信号量吗? 可以使用wait()notify()吗?
来实现package com.MultiThreading.threadSerialization;
import java.util.concurrent.Semaphore;
public class ThreadSerialization {
Semaphore a1Done = new Semaphore(0);
Semaphore b1Done = new Semaphore(0);
Semaphore a2Done = new Semaphore(0);
Semaphore b2Done = new Semaphore(0);
Semaphore a3Done = new Semaphore(0);
/**
* methodA prints : A1 A2 A3
*/
public void methodA() {
System.out.println("A1");
a1Done.release();
b1Done.acquire();
System.out.println("A2");
a2Done.release();
b2Done.acquire();
System.out.println("A3");
a3Done.release();
}
/**
* methodB prints : B1 B2 B3
*/
public void methodB() {
a1Done.acquire();
System.out.println("B1");
b1Done.release();
a2Done.acquire();
System.out.println("B2");
b2Done.release();
a3Done.acquire();
System.out.println("B3");
}
public void createTwoThreads() throws InterruptedException{
ThreadSerialization ts = new ThreadSerialization();
Thread T1 = new Thread(() -> ts.methodA());
Thread T2 = new Thread(() -> ts.methodB());
T1.start();
T2.start();
Thread.sleep(5000);
System.out.println("test done");
}
}
答案 0 :(得分:-1)
如果确保只有一个线程执行methodA
而另一个线程执行methodB
,则可以使用两个信号量。当您打印A1
时,您可以T2
打印B1
的可能性。然后需要等待A2
打印才能继续
Semaphore aPrintDone = new Semaphore(0);
Semaphore bPrintDone= new Semaphore(0);
/**
* methodA prints : A1 A2 A3
*/
public void methodA() {
try {
System.out.println("A1");
aPrintDone.release();
bPrintDone.acquire();
System.out.println("A2");
aPrintDone.release();
bPrintDone.acquire();
System.out.println("A3");
aPrintDone.release();
}catch (InterruptedException e1) {
e1.printStackTrace();
}
}
/**
* methodB prints : B1 B2 B3
*/
public void methodB() {
try {
aPrintDone.acquire();
System.out.println("B1");
bPrintDone.release();
aPrintDone.acquire();
System.out.println("B2");
bPrintDone.release();
System.out.println("B3");
}catch (InterruptedException e1) {
e1.printStackTrace();
}
}
使用wait()
和notify()
也可以解决此问题。考虑wait()
意味着线程将等待直到满足某个条件(在这种情况下是B打印,T1
;以及A打印线程T2
)。因此,当System.out.println
完成后,它可以notify()
另一个线程开始打印。我更喜欢信号量分辨率,但可以使用这些方法解决它。
答案 1 :(得分:-1)
回答wait-notify
问题:是的,这是可能的。它甚至只能使用一个锁定对象。但是代码既不是非常易读也不是“安全”。代码要求methodA()
在methodB()
之前执行,否则程序将死锁。
public class Synchronization {
synchronized public void methodA() {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("A1");
this.notify();
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("A2");
this.notify();
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("A3");
this.notify();
}
synchronized public void methodB() {
this.notify();
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("B1");
this.notify();
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("B2");
this.notify();
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("B3");
}
public static void main(String... args) throws InterruptedException {
Synchronization ts = new Synchronization();
Thread t1 = new Thread(ts::methodA);
Thread t2 = new Thread(ts::methodB);
t1.start(); // If you switch those lines,
t2.start(); // the program will deadlock.
t1.join();
t2.join();
System.out.println("test done");
}
}