Java 多线程:一个接一个地执行 2 个线程,在 java 中从 1 打印到 10



两个线程需要按这个顺序打印-

线程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();
}
}   
}
}
}

这个问题是在一次采访中问到的。请让我知道如何用示例代码解决这个问题。谢谢。

我不认为这是一个有用的任务,但它可以像

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版本很容易。此外,让第二个线程打印三个冒号而不是一个冒号(如果这真的是一个要求(,就不会那么难......

为每个线程使用一个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()调用会向信号量添加许可证,这可能会立即导致已经等待的线程开始执行,或者记住它,以便将来的某个线程可以在调用acquire()时继续执行,而无需进入等待状态。

测试(2 个线程(

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

输出

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

测试(4 个线程(

可与 2 个以上的线程一起使用:

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

输出

Thread1:0
Thread2:0
Thread3:0
Thread4:0
Thread1:1
Thread2:1
Thread3:1
Thread4:1
Thread1:2
Thread2:2
Thread3:2
Thread4:2
Thread1:3
Thread2:3
Thread3:3
Thread4:3
Thread1:4
Thread2:4
Thread3:4
Thread4:4
Thread1:5
Thread2:5
Thread3:5
Thread4:5
Thread1:6
Thread2:6
Thread3:6
Thread4:6
Thread1:7
Thread2:7
Thread3:7
Thread4:7
Thread1:8
Thread2:8
Thread3:8
Thread4:8
Thread1:9
Thread2:9
Thread3:9
Thread4:9
Thread1:10
Thread2:10
Thread3:10
Thread4:10

最新更新