no_russion
2019-09-11 23:34
采纳率: 50%
浏览 351
已采纳

多线程练习小问题 为什么这题notify不起作用

想要用多线程打印出12A34B56C78D.......
但是像这样写只能打出12,notify没有起作用,请问如何改动

public class 作业2
{

    public static void main(String[] args)
    {
        // TODO Auto-generated method stub
        new Thread(new Number()).start();
        new Thread(new Letter()).start();
    }

}

class Number implements Runnable
{
    private int n = 1;

    @Override
    public synchronized void run()
    {
        for (int i = 0; i < 52; i++)
        {
            if (i % 2 == 0 && i != 0)
            {
                try
                {
                    notify();;
                    this.wait();
                } catch (InterruptedException e)
                {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            System.out.print(n + i);
        }
    }
}

class Letter implements Runnable
{
    char a = 'a';

    @Override
    public synchronized void run()
    {
        try
        {
            wait();
        } catch (InterruptedException e1)
        {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

        for (int i = 0; i < 26; i++)
        {
            System.out.print(a + i);
            try
            {
                notify();
                this.wait();
            } catch (InterruptedException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

}
  • 写回答
  • 好问题 提建议
  • 追加酬金
  • 关注问题
  • 邀请回答

1条回答 默认 最新

  • 毕小宝 博客专家认证 2019-09-12 09:07
    最佳回答

    这里需要理解 Object 类的 wait() 和 notify() 、notifyAll() 的用法,它是针对内置条件队列的阻塞和唤醒,一旦调用 wait 后,当前线程已经挂起了,即使后面的代码用了 notify,也是无效的,必须由另一个线程调用 notify 才能唤醒它。所以这里的用法是错误的,你这里是定义了两个线程,各自操作自己的 wait 和 notify ,在调用 wait 后就挂起了自己,由于没有其他线程调用 notify ,所以线程都处于挂起状态的。

    正确的应该是在一个类的不同方法中,一个方法用 wait() 挂起,另一个方法中用 notify 唤醒。并且这两个方法应该由不同的线程来调用。
    参考下这篇 https://blog.csdn.net/wojiushiwo945you/article/details/42262149 的 InnerConditionQueue 的用法,再试试。

    demo 中启动了三个线程 + main 线程:

    Thu Sep 12 09:18:17 CST 2019 buffer is Not Full notify:tt1
    Thu Sep 12 09:18:17 CST 2019 buffer is Not Full notify:tt3
    Thu Sep 12 09:18:17 CST 2019 buffer is Full thread wait:tt2
    Thu Sep 12 09:18:22 CST 2019 main take:hello1
    Thu Sep 12 09:18:22 CST 2019 buffer is Not Full notify:tt2
    

    t1 put、t3 put 后队列满了,此时 t2 再 put 时遇上了 wait 而阻塞。
    maint 线程消费了一个后,唤醒了 t2 线程。即 wait 和 notify 必须由不同的线程调用,否则将无法唤醒。

    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题