1

我在两个不同的类中有两种方法,像这样

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

public class ClassY implements Runnable {

    public void methodAorB() {
        for(int i=0;i<10;i++) {
            System.out.println("This is A or B");
        }
    }

    @Override
    public void run() {
        methodAorB(a);
    }
}

线程t1正在调用methodAandB().

线程t2正在调用methodAorB().


每次迭代方法中的循环后,我可以在这两个线程之间切换吗?

我想得到这样的输出:

这是A和B

这是A或B

这是A和B

这是A或B

这是A和B

这是A或B

这是A和B

这是A或B

4

5 回答 5

2

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

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

Y 类

public class ClassY implements Runnable {
public  void methodAorB() {
    for(int i=0;i<10;i++) {
         while(GlobalClass.isClassYdone)
         {}
        System.out.println("This is A or B ");
        GlobalClass.isClassYdone = true;
        GlobalClass.isClassXdone = false;}}
@Override
public void run() {
    methodAorB();}}

共享变量的定义

public class GlobalClass {

public  static boolean isClassXdone = false ;
public  static boolean isClassYdone = false ;
}

您可以使用 t1.start 和 t2.start 启动线程以获得所需的输出

    Thread t1 = new Thread(new ClassX());
    Thread t2 = new Thread(new ClassY());
    t1.start();
    t2.start();
于 2014-05-13T12:26:32.053 回答
2

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

给定两个 int 数组(偶数和奇数),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();
                }
            }
        }

    }

}
于 2017-02-26T15:24:47.707 回答
0

这可能超出了解决问题的需要,但是,由于它似乎是对并发编程练习的介绍,它应该与您将遇到的内容相一致。

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

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

ClassY应该做同样的事情。等待它的轮到,做它的动作,然后将轮到另一个让步。

于 2013-03-20T17:58:16.100 回答
0

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

正如@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();
    }
}

然后,您可以按如下方式实现 ClassX。

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

ClassY 也将是相同的,无论您需要有什么不同。然后,在调用中(即在 main 方法中),

public static void main(String[] args) {
    MutEx mutEx = new MutEx(0, 2);
    Thread t1 = new Thread(new ClassX(0, mutEx);
    Thread t2 = new Thread(new ClassY(1, mutEx));
    t1.start();
    t2.start();
}

瞧!您有两个线程,根据需要在每个线程之间交替。

解决方案 2:或者,您可以按如下方式实现 ClassX 和 ClassY。

public class ClassX extends Thread{

在这里,您将子类化java.lang.Thread以实现您的要求。要调用它,请按如下方式更改 main 方法。

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

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

于 2016-11-23T15:48:31.040 回答
-3

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

for (int i = 0; i < 20; i++) {
    if (i % 2 == 0) {
        methodAandB();
    } else {
        methodAorB();
    }
}
于 2013-03-20T17:33:33.890 回答