Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/342.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在两个线程之间来回切换_Java_Multithreading_Synchronisation - Fatal编程技术网

Java 如何在两个线程之间来回切换

Java 如何在两个线程之间来回切换,java,multithreading,synchronisation,Java,Multithreading,Synchronisation,我在两个不同的类中有两个方法,如下所示 public class ClassX implements Runnable { public void methodAandB() { for(int i=0;i<10;i++) { System.out.println("This is A and B "); } } @Override public void run() { metho

我在两个不同的类中有两个方法,如下所示

public class ClassX implements Runnable {

    public  void methodAandB() {
        for(int i=0;i<10;i++) {
            System.out.println("This is A and B ");
        }
    }
    @Override
    public void run() {
        methodAandB();
    }
}
公共类ClassX实现可运行{
公共无效方法A和B(){

对于(int i=0;i如果不需要使用线程,请尝试以下代码:

for (int i = 0; i < 20; i++) {
    if (i % 2 == 0) {
        methodAandB();
    } else {
        methodAorB();
    }
}
for(int i=0;i<20;i++){
如果(i%2==0){
方法A和B();
}否则{
方法oRB();
}
}

如果不需要使用线程,请尝试以下代码:

for (int i = 0; i < 20; i++) {
    if (i % 2 == 0) {
        methodAandB();
    } else {
        methodAorB();
    }
}
for(int i=0;i<20;i++){
如果(i%2==0){
方法A和B();
}否则{
方法oRB();
}
}

这可能比解决问题所需的更多,但是,由于它似乎是对并发编程练习的介绍,因此它应该与您将遇到的内容保持一致

您可能应该拥有一个共享对象,您的两个线程都知道该对象,以便它们可以通过该对象进行同步。如下所示:

public class MyMutex {
    private int whoGoes;
    private int howMany;

    public MyMutex(int first, int max) {
        whoGoes = first;
        howMany = max;
    }

    public synchronized int getWhoGoes() { return whoGoes; }

    public synchronized void switchTurns() {
        whoGoes = (whoGoes + 1) % howMany;
        notifyAll();
    }

    public synchronized void waitForMyTurn(int id) throws
            InterruptedException {
        while (whoGoes != id) { wait(); }
    }
}

现在,您的类应该接收它们各自的标识符和这个共享对象

public class ClassX implements Runnable {
    private final int MY_ID;
    private final MyMutex MUTEX;

    public ClassX(int id, MyMutex mutex) {
        MY_ID = id;
        MUTEX = mutex;
    }

    public void methodAandB() {
        for(int i = 0; i < 10; i++) {
            try {
                MUTEX.waitForMyTurn(MY_ID);
                System.out.println("This is A and B ");
                MUTEX.switchTurns();
            } catch (InterruptedException ex) {
                // Handle it...
            }
        }
    }
    @Override
    public void run() { methodAandB(); }
}
公共类ClassX实现可运行{
私人最终输入我的ID;
私有最终MyMutex互斥;
公共类x(int-id,MyMutex-mutex){
我的ID=ID;
互斥=互斥;
}
公共无效方法A和B(){
对于(int i=0;i<10;i++){
试一试{
MUTEX.waitForMyTurn(我的ID);
System.out.println(“这是A和B”);
MUTEX.switchTurns();
}捕获(中断异常例外){
//处理它。。。
}
}
}
@凌驾
public void run(){methodAandB();}
}

ClassY
也应该这样做。等待轮到它的时候,做它的动作,然后让另一个轮到它。

这可能比解决问题所需要的更多,但是,因为它似乎是对并发编程练习的介绍,它应该与您将遇到的情况相一致

您可能应该拥有一个共享对象,您的两个线程都知道该对象,以便它们可以通过该对象进行同步。如下所示:

public class MyMutex {
    private int whoGoes;
    private int howMany;

    public MyMutex(int first, int max) {
        whoGoes = first;
        howMany = max;
    }

    public synchronized int getWhoGoes() { return whoGoes; }

    public synchronized void switchTurns() {
        whoGoes = (whoGoes + 1) % howMany;
        notifyAll();
    }

    public synchronized void waitForMyTurn(int id) throws
            InterruptedException {
        while (whoGoes != id) { wait(); }
    }
}

现在,您的类应该接收它们各自的标识符和这个共享对象

public class ClassX implements Runnable {
    private final int MY_ID;
    private final MyMutex MUTEX;

    public ClassX(int id, MyMutex mutex) {
        MY_ID = id;
        MUTEX = mutex;
    }

    public void methodAandB() {
        for(int i = 0; i < 10; i++) {
            try {
                MUTEX.waitForMyTurn(MY_ID);
                System.out.println("This is A and B ");
                MUTEX.switchTurns();
            } catch (InterruptedException ex) {
                // Handle it...
            }
        }
    }
    @Override
    public void run() { methodAandB(); }
}
公共类ClassX实现可运行{
私人最终输入我的ID;
私有最终MyMutex互斥;
公共类x(int-id,MyMutex-mutex){
我的ID=ID;
互斥=互斥;
}
公共无效方法A和B(){
对于(int i=0;i<10;i++){
试一试{
MUTEX.waitForMyTurn(我的ID);
System.out.println(“这是A和B”);
MUTEX.switchTurns();
}捕获(中断异常例外){
//处理它。。。
}
}
}
@凌驾
public void run(){methodAandB();}
}

ClassY
也应该这样做。等待轮到它,执行它的操作,然后让另一个轮到它。

你可以通过使用共享变量来实现这一点。我已经实现并验证了这个问题。代码如下所示

X类

public class ClassX implements Runnable {
public  void methodAandB() {
    for(int i=0;i<10;i++) {
        while(GlobalClass.isClassXdone)
        {}
        System.out.println("This is A and B ");
        GlobalClass.isClassXdone = true;
        GlobalClass.isClassYdone = false;
}}
@Override
public void run() {
    methodAandB(); } }
您可以使用t1.start和t2.start启动线程,以获得所需的输出

    Thread t1 = new Thread(new ClassX());
    Thread t2 = new Thread(new ClassY());
    t1.start();
    t2.start();

您可以通过使用共享变量来实现这一点。我已经实现并验证了这个问题。代码如下

X类

public class ClassX implements Runnable {
public  void methodAandB() {
    for(int i=0;i<10;i++) {
        while(GlobalClass.isClassXdone)
        {}
        System.out.println("This is A and B ");
        GlobalClass.isClassXdone = true;
        GlobalClass.isClassYdone = false;
}}
@Override
public void run() {
    methodAandB(); } }
您可以使用t1.start和t2.start启动线程,以获得所需的输出

    Thread t1 = new Thread(new ClassX());
    Thread t2 = new Thread(new ClassY());
    t1.start();
    t2.start();

我知道现在回答这个问题有点晚了。但现在是昨天,我才遇到这个问题。所以我想永远都不会太晚……)

解决方案,如@afsantos所述,是在两个线程之间拥有一个共享对象,并在共享对象上实现互斥。共享对象可以由两个线程交替锁定。两种可能的实现如下所示。这实际上更像是@afsantos解决方案的扩展。特此确认他的工作

解决方案1: 将被共享的对象的蓝图如下所示

public class MutEx {
    public int whoGoes, howMany;

    public MutEx(int whoGoes, int howMany) {
        this.whoGoes = whoGoes;
        this.howMany = howMany;
    }

    public synchronized void switchTurns(){
        this.whoGoes = (this.whoGoes + 1) % 2;
        notifyAll();
    }

    public synchronized void waitForTurn(int id) throws InterruptedException{
        while(this.whoGoes != id)
            wait();
    }
}
public class ClassX implements Runnable {
    private final int MY_ID;
    private final MutEx MUT_EX;

    public ThreadOne(int MY_ID, MutEx MUT_EX) {
        this.MY_ID = MY_ID;
        this.MUT_EX = MUT_EX;
    }

    @Override
    public void run(){
        this.doTheWork();
    }

    public void doTheWork(){
        for(int i = 0; i < 10; i++){
            try {
                MUT_EX.waitForMyTurn(MY_ID);
                System.out.println("This is A and B");
                MUT_EX.switchTurns();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
public class ClassX extends Thread{
public static void main(String[] args) {
    MutEx mutEx = new MutEx(0, 2);
    ClassX t1 = new ClassX(0, mutEx);
    ClassY t2 = new ClassY(1, mutEx);
    t1.start();
    t2.start();
}
然后,您可以实现ClassX,如下所示

public class MutEx {
    public int whoGoes, howMany;

    public MutEx(int whoGoes, int howMany) {
        this.whoGoes = whoGoes;
        this.howMany = howMany;
    }

    public synchronized void switchTurns(){
        this.whoGoes = (this.whoGoes + 1) % 2;
        notifyAll();
    }

    public synchronized void waitForTurn(int id) throws InterruptedException{
        while(this.whoGoes != id)
            wait();
    }
}
public class ClassX implements Runnable {
    private final int MY_ID;
    private final MutEx MUT_EX;

    public ThreadOne(int MY_ID, MutEx MUT_EX) {
        this.MY_ID = MY_ID;
        this.MUT_EX = MUT_EX;
    }

    @Override
    public void run(){
        this.doTheWork();
    }

    public void doTheWork(){
        for(int i = 0; i < 10; i++){
            try {
                MUT_EX.waitForMyTurn(MY_ID);
                System.out.println("This is A and B");
                MUT_EX.switchTurns();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
public class ClassX extends Thread{
public static void main(String[] args) {
    MutEx mutEx = new MutEx(0, 2);
    ClassX t1 = new ClassX(0, mutEx);
    ClassY t2 = new ClassY(1, mutEx);
    t1.start();
    t2.start();
}
瞧!你有两条线,每一条线根据需要交替

解决方案2:或者,您可以实现ClassX和ClassY,如下所示

public class MutEx {
    public int whoGoes, howMany;

    public MutEx(int whoGoes, int howMany) {
        this.whoGoes = whoGoes;
        this.howMany = howMany;
    }

    public synchronized void switchTurns(){
        this.whoGoes = (this.whoGoes + 1) % 2;
        notifyAll();
    }

    public synchronized void waitForTurn(int id) throws InterruptedException{
        while(this.whoGoes != id)
            wait();
    }
}
public class ClassX implements Runnable {
    private final int MY_ID;
    private final MutEx MUT_EX;

    public ThreadOne(int MY_ID, MutEx MUT_EX) {
        this.MY_ID = MY_ID;
        this.MUT_EX = MUT_EX;
    }

    @Override
    public void run(){
        this.doTheWork();
    }

    public void doTheWork(){
        for(int i = 0; i < 10; i++){
            try {
                MUT_EX.waitForMyTurn(MY_ID);
                System.out.println("This is A and B");
                MUT_EX.switchTurns();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
public class ClassX extends Thread{
public static void main(String[] args) {
    MutEx mutEx = new MutEx(0, 2);
    ClassX t1 = new ClassX(0, mutEx);
    ClassY t2 = new ClassY(1, mutEx);
    t1.start();
    t2.start();
}
在这里,您正在子类化
java.lang.Thread
,以实现您的需求

public class MutEx {
    public int whoGoes, howMany;

    public MutEx(int whoGoes, int howMany) {
        this.whoGoes = whoGoes;
        this.howMany = howMany;
    }

    public synchronized void switchTurns(){
        this.whoGoes = (this.whoGoes + 1) % 2;
        notifyAll();
    }

    public synchronized void waitForTurn(int id) throws InterruptedException{
        while(this.whoGoes != id)
            wait();
    }
}
public class ClassX implements Runnable {
    private final int MY_ID;
    private final MutEx MUT_EX;

    public ThreadOne(int MY_ID, MutEx MUT_EX) {
        this.MY_ID = MY_ID;
        this.MUT_EX = MUT_EX;
    }

    @Override
    public void run(){
        this.doTheWork();
    }

    public void doTheWork(){
        for(int i = 0; i < 10; i++){
            try {
                MUT_EX.waitForMyTurn(MY_ID);
                System.out.println("This is A and B");
                MUT_EX.switchTurns();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
public class ClassX extends Thread{
public static void main(String[] args) {
    MutEx mutEx = new MutEx(0, 2);
    ClassX t1 = new ClassX(0, mutEx);
    ClassY t2 = new ClassY(1, mutEx);
    t1.start();
    t2.start();
}

运行这个,你会得到同样的结果。

我知道现在回答这个问题有点晚了。但现在是昨天,我才遇到这个问题。所以我想永远都不会太晚。)

解决方案,如@afsantos所述,是在两个线程之间拥有一个共享对象,并在共享对象上实现互斥。共享对象可以由两个线程交替锁定。两种可能的实现如下所示。这实际上更像是@afsantos解决方案的扩展。特此确认他的工作

解决方案1: 将被共享的对象的蓝图如下所示

public class MutEx {
    public int whoGoes, howMany;

    public MutEx(int whoGoes, int howMany) {
        this.whoGoes = whoGoes;
        this.howMany = howMany;
    }

    public synchronized void switchTurns(){
        this.whoGoes = (this.whoGoes + 1) % 2;
        notifyAll();
    }

    public synchronized void waitForTurn(int id) throws InterruptedException{
        while(this.whoGoes != id)
            wait();
    }
}
public class ClassX implements Runnable {
    private final int MY_ID;
    private final MutEx MUT_EX;

    public ThreadOne(int MY_ID, MutEx MUT_EX) {
        this.MY_ID = MY_ID;
        this.MUT_EX = MUT_EX;
    }

    @Override
    public void run(){
        this.doTheWork();
    }

    public void doTheWork(){
        for(int i = 0; i < 10; i++){
            try {
                MUT_EX.waitForMyTurn(MY_ID);
                System.out.println("This is A and B");
                MUT_EX.switchTurns();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
public class ClassX extends Thread{
public static void main(String[] args) {
    MutEx mutEx = new MutEx(0, 2);
    ClassX t1 = new ClassX(0, mutEx);
    ClassY t2 = new ClassY(1, mutEx);
    t1.start();
    t2.start();
}
然后,您可以实现ClassX,如下所示

public class MutEx {
    public int whoGoes, howMany;

    public MutEx(int whoGoes, int howMany) {
        this.whoGoes = whoGoes;
        this.howMany = howMany;
    }

    public synchronized void switchTurns(){
        this.whoGoes = (this.whoGoes + 1) % 2;
        notifyAll();
    }

    public synchronized void waitForTurn(int id) throws InterruptedException{
        while(this.whoGoes != id)
            wait();
    }
}
public class ClassX implements Runnable {
    private final int MY_ID;
    private final MutEx MUT_EX;

    public ThreadOne(int MY_ID, MutEx MUT_EX) {
        this.MY_ID = MY_ID;
        this.MUT_EX = MUT_EX;
    }

    @Override
    public void run(){
        this.doTheWork();
    }

    public void doTheWork(){
        for(int i = 0; i < 10; i++){
            try {
                MUT_EX.waitForMyTurn(MY_ID);
                System.out.println("This is A and B");
                MUT_EX.switchTurns();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
public class ClassX extends Thread{
public static void main(String[] args) {
    MutEx mutEx = new MutEx(0, 2);
    ClassX t1 = new ClassX(0, mutEx);
    ClassY t2 = new ClassY(1, mutEx);
    t1.start();
    t2.start();
}
瞧!你有两条线,每一条线根据需要交替

解决方案2:或者,您可以实现ClassX和ClassY,如下所示

public class MutEx {
    public int whoGoes, howMany;

    public MutEx(int whoGoes, int howMany) {
        this.whoGoes = whoGoes;
        this.howMany = howMany;
    }

    public synchronized void switchTurns(){
        this.whoGoes = (this.whoGoes + 1) % 2;
        notifyAll();
    }

    public synchronized void waitForTurn(int id) throws InterruptedException{
        while(this.whoGoes != id)
            wait();
    }
}
public class ClassX implements Runnable {
    private final int MY_ID;
    private final MutEx MUT_EX;

    public ThreadOne(int MY_ID, MutEx MUT_EX) {
        this.MY_ID = MY_ID;
        this.MUT_EX = MUT_EX;
    }

    @Override
    public void run(){
        this.doTheWork();
    }

    public void doTheWork(){
        for(int i = 0; i < 10; i++){
            try {
                MUT_EX.waitForMyTurn(MY_ID);
                System.out.println("This is A and B");
                MUT_EX.switchTurns();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
public class ClassX extends Thread{
public static void main(String[] args) {
    MutEx mutEx = new MutEx(0, 2);
    ClassX t1 = new ClassX(0, mutEx);
    ClassY t2 = new ClassY(1, mutEx);
    t1.start();
    t2.start();
}
在这里,您正在子类化
java.lang.Thread
,以实现您的需求

public class MutEx {
    public int whoGoes, howMany;

    public MutEx(int whoGoes, int howMany) {
        this.whoGoes = whoGoes;
        this.howMany = howMany;
    }

    public synchronized void switchTurns(){
        this.whoGoes = (this.whoGoes + 1) % 2;
        notifyAll();
    }

    public synchronized void waitForTurn(int id) throws InterruptedException{
        while(this.whoGoes != id)
            wait();
    }
}
public class ClassX implements Runnable {
    private final int MY_ID;
    private final MutEx MUT_EX;

    public ThreadOne(int MY_ID, MutEx MUT_EX) {
        this.MY_ID = MY_ID;
        this.MUT_EX = MUT_EX;
    }

    @Override
    public void run(){
        this.doTheWork();
    }

    public void doTheWork(){
        for(int i = 0; i < 10; i++){
            try {
                MUT_EX.waitForMyTurn(MY_ID);
                System.out.println("This is A and B");
                MUT_EX.switchTurns();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
public class ClassX extends Thread{
public static void main(String[] args) {
    MutEx mutEx = new MutEx(0, 2);
    ClassX t1 = new ClassX(0, mutEx);
    ClassY t2 = new ClassY(1, mutEx);
    t1.start();
    t2.start();
}

运行此命令,您将得到相同的结果。

线程间触发器的最佳示例:

给定两个整数数组(偶数和奇数),2个线程按自然顺序打印它们的数字

package com.rough;

public class ThreadsBehaviour {

    static Object lock = new Object();

    public static void main(String[] args) throws InterruptedException {

        int a[] = {1,3,5,7,9};
        int b[] = {2,4,6,8,10};

        Thread odd = new Thread(new Looper(a, lock));
        Thread even = new Thread(new Looper(b, lock));

        odd.start();
        even.start();
    }

}

class Looper implements Runnable
{

    int a[];
    Object lock;

    public Looper(int a[], Object lock)
    {
        this.a = a;
        this.lock = lock;
    }
    @Override
    public void run() {

        for(int i = 0; i < a.length; i++)
        {
            synchronized(lock)
            {

                System.out.print(a[i]);
                try 
                {
                    lock.notify();
                    if(i == (a.length - 1))
                    {
                        break;
                    }
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

    }

}
package.com.rough;
公共类线程行为{
静态对象锁=新对象();
公共静态void main(字符串[]args)引发InterruptedException{
int a[]={1,3,5,7,9};
int b[]={2,4,6,8,10};
螺纹奇数=新螺纹(新活套(a,锁));
偶数线程=新线程(新活套(b,锁));
奇。开始();
偶数。开始();
}
}
类循环器实现Runnabl