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

时间:2017-07-13 15:54:01

标签: java multithreading concurrency

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

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

        }   
    }
}
}

这个问题是在接受采访时提出的。请通过示例代码告诉我如何解决这个问题。感谢。

2 个答案:

答案 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