两个线程需要按此顺序打印 -
线程1:0
线程2 ::: 0
线程1:1
线程2 ::: 1
线程1:2
线程2 ::: 2
线程1:3
线程2 ::: 3
线程1:10
线程2 ::: 10
我目前的情况如下:
package sample;
public class ThreadExecutionOrder {
public static void main(String[] args) throws InterruptedException {
ThreadExecutionOrder th=new ThreadExecutionOrder();
Thread1 t1= new Thread1(th);
Thread t2 = new Thread2(th);
t1.start();
t2.start();
}
}
class Thread1 extends Thread{
ThreadExecutionOrder th;
Thread1(ThreadExecutionOrder th){
this.th=th;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("Thread1:"+i);
synchronized(th){
try {
th.wait();
th.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
class Thread2 extends Thread{
ThreadExecutionOrder th;
Thread2(ThreadExecutionOrder th){
this.th=th;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("Thread2:::"+i);
synchronized(th){
th.notify();
try {
th.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
这个问题是在接受采访时提出的。请通过示例代码告诉我如何解决这个问题。感谢。
答案 0 :(得分:1)
我认为这不是一项有用的任务,但可以像
一样实施ExecutorService es = Executors.newFixedThreadPool(2);
Phaser phaser = new Phaser(2);
for(int i = 0; i<2; i++) {
int thread = i;
es.execute(() -> {
String name = "Thread "+(thread+1)+": ";
for(int turn=0; turn<22; turn++) {
phaser.arriveAndAwaitAdvance();
if((turn&1)==thread)
System.out.println(name+turn/2);
}
});
}
es.shutdown();
lambda表达式只是一个语法事物,不是程序逻辑所必需的。在Java 8之前将它转换为Java版本会很容易。另外,让第二个线程打印三个冒号而不是一个(如果这确实是一个要求),就不会那么难......
答案 1 :(得分:0)
为每个线程使用Semaphore
,授予它打印下一行输出的权限,如下所示:
public class CounterThread extends Thread {
private final Semaphore mySemaphore;
private final Semaphore nextSemaphore;
public CounterThread(String name, Semaphore mySemaphore, Semaphore nextSemaphore) {
super(name);
this.mySemaphore = mySemaphore;
this.nextSemaphore = nextSemaphore;
}
@Override
public void run() {
try {
for (int i = 0; i <= 10; i++) {
this.mySemaphore.acquire();
System.out.println(getName() + ":" + i);
this.nextSemaphore.release();
}
} catch (InterruptedException e) {
e.printStackTrace(System.out);
}
}
}
使用对象监视器,notify()
调用仅发出已在等待的线程的信号。如果当前没有线程正在等待,则信号“丢失”。
使用信号量,release()
调用会向信号量添加一个许可证,这可以立即导致已经等待的线程开始执行,或者记住它,以便将来某个线程在调用时可以继续执行{{1}没有进入等待状态。
测试(2个主题)
acquire()
输出
Semaphore s1 = new Semaphore(0);
Semaphore s2 = new Semaphore(0);
new CounterThread("Thread1", s1, s2).start();
new CounterThread("Thread2", s2, s1).start();
s1.release(); // Start the counting
测试(4个主题)
可以使用2个以上的线程:
Thread1:0
Thread2:0
Thread1:1
Thread2:1
Thread1:2
Thread2:2
Thread1:3
Thread2:3
Thread1:4
Thread2:4
Thread1:5
Thread2:5
Thread1:6
Thread2:6
Thread1:7
Thread2:7
Thread1:8
Thread2:8
Thread1:9
Thread2:9
Thread1:10
Thread2:10
输出
Semaphore s1 = new Semaphore(0);
Semaphore s2 = new Semaphore(0);
Semaphore s3 = new Semaphore(0);
Semaphore s4 = new Semaphore(0);
new CounterThread("Thread1", s1, s2).start();
new CounterThread("Thread2", s2, s3).start();
new CounterThread("Thread3", s3, s4).start();
new CounterThread("Thread4", s4, s1).start();
s1.release(); // Start the counting