在Inter线程进程中,为什么主线程表现不好,当孩子先执行时?

时间:2017-03-23 12:34:51

标签: java multithreading

我正在学习java中的线程并编写以下代码。 这里: 我正在创建两个线程(main和t),我想实现线程间通信。这有两种情况:

1)如果主线程先执行/继续,则主线程获取对象“t”的锁定,释放锁定并进入等待状态(

synchronized (t) {
    System.out.println("waiting " + Thread.currentThread().getName() + " " + System.currentTimeMillis());
    t.wait();
}

)。子线程发生并完成其工作并通知主线程。主线程开始并打印最终输出System.out.println(t.total)。对我来说没关系。

2)如果先执行子线程,则子线程完成其工作(

synchronized (this) {
    for (int i = 0; i < 100 ; i++) {
        total = total + i;
    }
    System.out.println("------------" + Thread.currentThread().getName() + "calling notify" + System.currentTimeMillis());
    this.notify();
   }

)并最后致电通知。当它的通知被通知时会发生什么,因为没有人在等待?接下来的问题是主线程是否正在等待生命时间?如果没有,那么为什么不等待。

以下是代码。

public class Test {
    public static void main(String[] args) throws InterruptedException {
        T t = new T();
        t.setPriority(10);
        t.start();

        System.out.println();
        System.out.println();

        synchronized (t) {
            System.out.println("waiting " + Thread.currentThread().getName() + " " + System.currentTimeMillis());
            t.wait();
        }
        System.out.println(t.total);
    }
}

class T extends Thread {
    public int total = 0;
    public void run() {
        synchronized (this) {
            for (int i = 0; i < 100 ; i++) {
                total = total + i;
            }
            System.out.println("------------" + Thread.currentThread().getName() + "calling notify" + System.currentTimeMillis());
            this.notify();
        }
    }
}

问题:当子线程首次运行时,程序(主线程)结束/完成成功或一段时间主线程等待,为什么???

以下是输出:

------------Thread-0calling notify1490271423920

waiting main 1490271423921

在这种情况下,主线程处于活动状态。

------------Thread-0calling notify1490272176789
waiting main 1490272176789
4950

在这种情况下,主线程成功结束。 为什么会这样?

感谢。

2 个答案:

答案 0 :(得分:3)

  

当呼叫通知时会发生什么,因为没有人在等待?

什么都没发生。

  

下一个问题是主线程是否正在等待生命时间?如果没有,那么为什么不等待。

抱歉,我不明白你的问题。

  

问题:当子线程首次运行时,程序(主线程)结束/完成成功或一段时间主线程等待,为什么???

如果在this.notify()之前执行t.wait(),那么主线程将永远等待,挂起程序执行。

根据你的代码设计,我猜你想要,按照这个特殊的顺序:

  • 启动T线程的主线程和wait()
  • 然后是T线程来运行其代码并调用notify()
  • 然后主线程打印结果并完成

但是您的代码允许竞争条件,因为第二颗子弹可能在第一颗子弹完成之前开始和结束,从而导致不良行为。

答案 1 :(得分:1)

有许多与使用wait / notify相关的最佳实践。所有这些信息都可在线获取。一些关键点:

  • 使用notifyAll,除非您确实知道自己在做什么
  • 循环中始终wait(虚假唤醒)
  • 使用额外的&#34;状态&#34;反映当前共享状态的变量。通知并不反映任何状态,它只会唤醒正在等待的其他人。

最后一点与您当前的问题最为相关。当您notifyAll时,您还应设置某种反映通知意图的状态。

e.g。

 // thread
 sync() {
   done = true;
   notifyAll()
 }

 // main
 sync() {
   while(!done) {
     wait();
   }
 }