【问题标题】:Can some one explain why program doesn't end?有人可以解释为什么程序没有结束吗?
【发布时间】:2017-10-28 11:50:30
【问题描述】:

您好,我是 java 线程的新手。我想弄清楚什么是 wait() 和 notify() 方法。所以我写了简单的程序,但我不能 找到无限执行的原因。请问有人可以帮我解决这个问题吗?

public class StairCase {
    public static void main(String[] args) {
        int[] lst = {1,2,3,4,5,6,7};
        Test1 t1 = new Test1(lst);
        t1.setName("Test 1 ");
        Test2 t2 = new Test2(lst);
        t2.setName("Test 2 ");
        t1.start();
        t2.start();
    }
}

class Test1 extends Thread {
    int[] line ;
    public Test1(int[] lst) {
        this.line = lst;
    }
    public void run(){
        synchronized(line) {
            for (int i = 0; i < 5; i++) {
                try{
                    if(i == 2) line.wait();
               } catch (Exception e) {

               }
               System.out.println(Thread.currentThread().getName() + line[i]);
            }
        }
    }

}

class Test2 extends Thread {
    int[] line ;
    public Test2(int[] lst) {
        this.line = lst;
    }
    public void run() {
        synchronized(line) {
            for (int i = 0; i < 5; i++) {
                System.out.println(Thread.currentThread().getName() + line[i]);
            }
        }
        try {
            line.notify();
        } catch(Exception e) {
        }
    }
}

【问题讨论】:

  • 你的任务完成后有没有尝试过system.exit(0)?
  • 你的代码在第 45 行得到了 java.lang.IllegalMonitorStateException。
  • 是的。我认为问题出在线程中。但我无法弄清楚。
  • catch (Exception ex) { } 是在尝试调试程序时彻底迷惑自己的绝佳方式。当异常发生时,它们会悄无声息地消失在一个深深的黑洞中,而你却一无所知。绝不,绝不,绝不,绝不在任何情况下对自己造成如此残酷的伤害。至少把ex.printStackTrace();放在那里。
  • o.wait() 和 o.notify() 的 javadoc 没有解释它们的用途。请参阅教程:docs.oracle.com/javase/tutorial/essential/concurrency/…

标签: java multithreading concurrency wait notify


【解决方案1】:
public class StairCase {
    public static void main(String[] args) {
        int[] lst = {1,2,3,4,5,6,7};
        Test1 t1 = new Test1(lst);
        t1.setName("Test 1 ");
        Test2 t2 = new Test2(lst);
        t2.setName("Test 2 ");
        t1.start();
        t2.start();
    }
}

class Test1 extends Thread {
    private final int[] line ;
    Test1(int[] lst) {
        this.line = lst;
    }
    public void run(){
        synchronized(line) {
            for (int i = 0; i < 5; i++) {
                try{
                    if(i == 2) line.wait();
                } catch (Exception e) {
                  e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + line[i]);
            }
        }
    }

}

class Test2 extends Thread {
    private final int[] line ;
    Test2(int[] lst) {
        this.line = lst;
    }
    public void run() {
        synchronized(line) {
            for (int i = 0; i < 5; i++) {
                System.out.println(Thread.currentThread().getName() + line[i]);
            }
        }
        try {
            synchronized (line) {
                line.notify();
            }
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}

试试这段代码这是你预期的结果吗?如果不让我知道预期结果是什么。

我添加了 e.printStackTrace();到 catch 块并检查天气是否有异常,并且有异常,异常在 notify() 的第 45 行,所以我用同步语句包围了 notify。

        synchronized (line) {
            line.notify();
        }

【讨论】:

  • 解释您的代码以及它如何回答 OP 的问题。没有解释的大代码丢失是没有用的。
  • @ErwinBolwidt 大部分是 OP 的代码,但我会进行编辑并说明我所做的更改。
  • 首先我想在 t1 线程中打印 1 和 2 并等待 t1。接下来在 t2 线程中打印 1 到 5 并通知 t1 线程。然后打印 3 到 5。
  • 是的,我提供的代码就是这样做的。你只需要同步它,快乐的编码:)
猜你喜欢
  • 2021-03-04
  • 1970-01-01
  • 2012-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-21
  • 2019-10-28
  • 2016-06-01
相关资源
最近更新 更多