为了账号安全,请及时绑定邮箱和手机立即绑定

Java:如何让2个线程交替使用一个方法

Java:如何让2个线程交替使用一个方法

绝地无双 2021-06-05 08:46:57
对 Threads 有点陌生。我有 2 个线程并希望它们交替使用一种方法。所以线程 1 执行该方法,然后等待。然后线程 2 唤醒线程 1 并执行该方法。然后线程 1 唤醒线程 2 并执行该方法等。但不知何故我陷入了僵局,我不明白为什么。public class NewT extends Thread{public void print(NewT x){    synchronized(this)    {        System.out.println("x"+x);        notifyAll();        try {            wait();        } catch (InterruptedException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}public void run(){    for(int i=0;i<10;i++)    {        print(this);                    }}public static void main(String[] args) {    // TODO Auto-generated method stub    NewT one = new NewT();    NewT two = new NewT();    one.start();    two.start();}}
查看完整描述

3 回答

?
九州编程

TA贡献1785条经验 获得超4个赞

由于synchronized是对this每个线程锁定其自己的对象,而实际上没有同步; 他们正在等待一个永远不会到来的事件。


更新:


正如有人指出的那样,使用公共lock对象是不够的,因为两个线程最终都会等待。


这是一个解决方案:


private static Object lock = new Object();

private static NewT previous;


public static void print(NewT x) throws InterruptedException

{

    synchronized(lock) {

        while (previous == x) {

            lock.wait();

        }

        System.out.println("x"+ x);

        previous = x;

        lock.notifyAll();

    }

}


查看完整回答
反对 回复 2021-06-10
?
侃侃尔雅

TA贡献1801条经验 获得超16个赞

Wait(),notify()并且notifyAll()在共享公共/共享对象时工作正常。在您的情况下,您正在通知自己(同一线程实例)并等待无限期。结果 JVM 无法在 2 个条目后打印。


示例代码:


package ThreadsTricks;


/**

 *

 * @author pcu

 */


public class PrintOddEven {


boolean odd;

int count = 1;

int MAX = 20;


public void printOdd() {

    synchronized (this) {

        while (count < MAX) {

            System.out.println("Checking odd loop");


            while (!odd) {

                try {

                    System.out.println("Odd waiting : " + count);

                    wait();

                    System.out.println("Notified odd :" + count);

                } catch (InterruptedException e) {

                    // TODO Auto-generated catch block

                    e.printStackTrace();

                }

            }

            System.out.println("Odd Thread :" + count);

            count++;

            odd = false;

            notify();

        }

    }

}


public void printEven() {


    try {

      //  Thread.sleep(1000);

    } catch (Exception e1) {

        e1.printStackTrace();

    }

    synchronized (this) {

        while (count < MAX) {

            System.out.println("Checking even loop");


            while (odd) {

                try {

                    System.out.println("Even waiting: " + count);

                    wait();

                    System.out.println("Notified even:" + count);

                } catch (InterruptedException e) {

                    e.printStackTrace();

                }

            }

            System.out.println("Even thread :" + count);

            count++;

            odd = true;

            notify();


        }

    }

}


public static void main(String[] args) {


    PrintOddEven oddEven= new PrintOddEven();

    oddEven.odd = true;

    Thread t1 = new Thread(new Runnable() {


        @Override

        public void run() {

            oddEven.printEven();


        }

    });

    Thread t2 = new Thread(new Runnable() {


        @Override

        public void run() {

            oddEven.printOdd();


        }

    });


    t1.start();

    t2.start();


    try {

        t1.join();

        t2.join();

    } catch (Exception e) {

        e.printStackTrace();

    }


}

这是我的第一个回答,如果有任何问题,请告诉我。


查看完整回答
反对 回复 2021-06-10
  • 3 回答
  • 0 关注
  • 150 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信