Java 线程同步-如何交替执行线程

Java 线程同步-如何交替执行线程,java,multithreading,synchronization,wait,Java,Multithreading,Synchronization,Wait,我一直在尝试使用wait()和notify()解决一个涉及线程通信的问题。基本上我有两个线程T1和T2,我希望它们按照以下顺序执行 T1,T2,T1,T2。。。。。我怎样才能做到这一点 实际问题:有两个线程T1-打印奇数(比如1-100)和T2-打印偶数(1-100)。现在,输出应该是1,2,3,4,5。。。。100您正在尝试并行化多步骤流程,对吗?如果是这样的话,请参阅我的答案,以获得一种方法和一些实现这一点的工作代码。答案包括一个执行器服务(或两个)和一个或多个工作队列 对于这种方法,您的处

我一直在尝试使用wait()和notify()解决一个涉及线程通信的问题。基本上我有两个线程T1和T2,我希望它们按照以下顺序执行

T1,T2,T1,T2。。。。。我怎样才能做到这一点


实际问题:有两个线程T1-打印奇数(比如1-100)和T2-打印偶数(1-100)。现在,输出应该是1,2,3,4,5。。。。100

您正在尝试并行化多步骤流程,对吗?如果是这样的话,请参阅我的答案,以获得一种方法和一些实现这一点的工作代码。答案包括一个执行器服务(或两个)和一个或多个工作队列

对于这种方法,您的处理需要能够适应Runnable,以及处理的中间状态信息将每个步骤作为
可运行的
馈送到
执行器服务
,这将添加第二个可运行的,以执行下一步。
这将保持执行顺序,但可以有效地并行运行任意多个线程

:编辑:


正如另一个人所建议的,如果您明确地希望将处理限制为2个线程,则可以使用library类来实现这一点。我更喜欢上面的方法,因为它保持了执行顺序,并允许您充分使用现代的4核(和8核)系统。它还应该减少一点同步。

您描述了生产者-消费者模式

许多java书籍中都描述了它的java实现,包括M.Grand的《java.Volume I中的模式》和Nouton和Schildt的《Java2:完整参考》

基本思想:两个线程都应该使用一个监视器(即,它们的代码应该在
synchronized(monitor){}
块中)。您还需要一些标志变量,该变量应指示两个线程中的哪一个此时应该工作


当您的一个线程在同步块中时,它应该检查标志变量是否轮到他来执行该任务。如果是,让它工作,然后更改标志值,然后通知所有等待的线程。如果不是,那么它应该等待。

看看java.util.concurrent包,特别是如果T1和T2是可运行接口的两个不同实现,T1是一个只打印奇数(1,3…)的线程,T2是一个打印偶数(1,2…)的线程,这可以通过使用wait()和notify()来完成共享监视器上的方法。重要的是每个线程在打印其值之前检查共享标志。以下代码有效

//The shared monitor
public class Mutex {
public static boolean oddFlag;

}

//The Thread that is supposed to print Odd numbers (assuming an upper limit of 99)
public class OddPrinter implements Runnable {
private Mutex mutex;

public OddPrinter(Mutex mutex) {
    this.mutex = mutex;
}

public synchronized void run() {
    System.out.println("Started Thread: OddPrinter");
    int i;
    for(i=1; i<100; i+=2 ) {
        synchronized (mutex) {
            while(!Mutex.oddFlag) {
                try {
                    mutex.wait();
                } catch (InterruptedException ie) {
                    Thread.currentThread().interrupted();
                }
            }

            if(Mutex.oddFlag == true) {
                System.out.println("Print from OddPrinter: "+i);
                Mutex.oddFlag = false;
                mutex.notify();
            }


        }
    }
    System.out.println("Finished Thread: OddPrinter: "+i);
}

}

//The Thread that is supposed to print Odd numbers (assuming an upper limit of 98)
public class EvenPrinter implements Runnable {
private Mutex mutex;

public EvenPrinter(Mutex mutex) {
    this.mutex = mutex;
}

public synchronized void run() {
    System.out.println("Started Thread: EvenPrinter");
    int i;
    for(i=2; i<100; i+=2) {
        synchronized (mutex) {
            while(Mutex.oddFlag) {
                try {
                    mutex.wait();
                } catch (InterruptedException ie) {
                    Thread.currentThread().interrupted();
                }
            }

            if(!(Mutex.oddFlag == true)) {
                System.out.println("Print from EvenPrinter: "+i);
                Mutex.oddFlag = true;
                mutex.notify();
            }

        }
    }
    System.out.println("Finished Thread: EvenPrinter: "+i);
}

}

//The test harness that executes the threads
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class NumberPrinterTest {

public static void main(String[] args) throws Exception{
    ExecutorService es = Executors.newFixedThreadPool(2);

    Mutex mutex = new Mutex();
    OddPrinter op = new OddPrinter(mutex);
    EvenPrinter ep = new EvenPrinter(mutex);
    Mutex.oddFlag = true;
    es.execute(op);
    es.execute(ep);

    if(null != es){
        es.shutdown();
        try {
            es.awaitTermination(1, TimeUnit.MINUTES);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupted();
        }
    }

}

}
//共享监视器
公共类互斥{
公共静态标志;
}
//应该打印奇数的线程(假设上限为99)
公共类实现Runnable{
专用互斥;
公用打印机(互斥互斥){
this.mutex=mutex;
}
公共同步的无效运行(){
System.out.println(“启动线程:OddPrinter”);
int i;

对于(i=1;i在单个线程中运行任务?如果要同步某些内容,为什么要使用线程运行?我生成了两个线程。我希望它们与首先执行的第一个线程交替执行这比在一个线程中运行代码有什么好处?我想这是关于同步的家庭作业问题,ra这不是一个需要解决的实际问题。它并不完全是这样。基本上我有两个线程,假设一个打印a,另一个打印b。现在我想打印一个序列ababab…@sai您可以使用生产者-消费者的解决方案作为解决方案。