【问题标题】:How to make a thread wait for some time after current thread executes some statements当前线程执行某些语句后如何使线程等待一段时间
【发布时间】:2015-06-07 19:36:08
【问题描述】:

我是 MultiThreading 的新手,我正在编写一个应用程序,因为我有两个线程 T1 和 T2。 在 T1 我有 15 条要打印的语句,而 T2 我有 15 条要打印的语句。 我喜欢在 T1 执行语句 5 后等待 T2 一段时间,并在 T1 执行语句 10 后继续 T2。 我已经写了代码,但是 T2 没有等待,谁能解释一下。

线程一:T1

public class ThreadOne extends Thread {

public void run() {



    for (int i = 1; i <= 15; i++) {

        System.out.println("This is Thread One " + i);

        if (i == 5) {
            synchronized (Test.threadB) {
                try {
                    Test.threadB.wait();
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
            }
        } else if (i == 10) {
            synchronized (Test.threadB) {
                Test.threadB.notify();
            }
        }


    }


}
}  

线程二:T2

public class ThreadTwo extends Thread {

public void run() {

    for (int i = 1; i <= 15; i++) {

        System.out.println("This is Thread Two " + i);
    }


}
}  

测试:

public class Test {

static Thread threadA = null;
static Thread threadB = null;

public static void main(String[] args) throws InterruptedException {

    threadA = new ThreadOne();
    threadB = new ThreadTwo();

    threadA.start();
    threadB.start();


}
}

我对 O/P 的期望:
T1 执行后 Test.threadB.wait();当 i 为 5 时,无需打印 T2 语句。 T1 i 为 10 后,T2 可以开始打印。

但我得到的 O/p 是:

This is Thread One 1
This is Thread One 2
This is Thread One 3
This is Thread Two 1
This is Thread Two 2
This is Thread One 4
This is Thread Two 3
This is Thread One 5
This is Thread Two 4
This is Thread Two 5
This is Thread Two 6
This is Thread Two 7
This is Thread Two 8
This is Thread Two 9
This is Thread Two 10
This is Thread Two 11
This is Thread Two 12
This is Thread Two 13
This is Thread Two 14
This is Thread Two 15
This is Thread One 6
This is Thread One 7
This is Thread One 8
This is Thread One 9
This is Thread One 10
This is Thread One 11
This is Thread One 12
This is Thread One 13
This is Thread One 14
This is Thread One 15 

为什么只有 T2 语句在 T1 i==5 或(这是线程一 5 被打印)之后执行?请任何人解释一下。

【问题讨论】:

  • 你认为Test.threadB.wait(); 做了什么,你为什么这么认为?
  • 我希望 T2 等待你认为 Test.threadB.wait(); 为何能做到这一点?
  • 并不是说它可以解决任何问题,但您应该避免扩展线程。而是为Runnable 创建实现并将其传递给线程。还要避免在 Thread 上同步。
  • 导致当前线程调用Test.threadB.wait();时是哪个当前线程?
  • 开始区分线程和Thread 对象。 Thread#start() 启动一个由对应的Thread 对象标识的线程。代码正在该(当前)线程中执行,并在某些时候调用Test.threadB.wait()。当前线程是什么?

标签: java multithreading wait


【解决方案1】:

我更喜欢使用来自java.util.concurrent 的类/接口而不是wait/notify,因为我相信它使代码更具可读性/不易出现同步错误。在您的情况下,您可以使用ThreadOne 和ThreadTwo 之间共享的Semaphore 来暂停和恢复ThreadTwo - 使用一个许可初始化信号量,在每次迭代ThreadTwo 调用availablePermits() 并且如果有一个可用的许可(返回值 > 0)然后它继续,否则它调用acquire() 导致线程阻塞,直到许可可用。 ThreadOne 调用 drainPermits() 暂停 ThreadTwo,然后调用 release() 以允许 ThreadTwo 恢复。

正如 Pshemo 在 cmets 中所指出的,实现 Runnable 而不是扩展 Thread 是一种很好的做法 - 这样可以避免混淆您的类,还可以让您使用 ExecutorService 来池线程。

Runnable runnableOne = // ...
Runnable runnableTwo = // ...
ExecutorService executor = Executors.newFixedThreadPool(2);
executor.submit(runnableOne);
executor.submit(runnableTwo);

【讨论】:

  • 这很好,但请以回答 OP 问题的方式表达它。
  • 同意答案,我也会选择 ExecutorService / Callable 组合。
  • @SotiriosDelimanolis 我将这个问题读作“我如何获得这种行为,并且对实施没有限制”,在这种情况下,我相信他会更好地学习 java.util.concurrent 而不是 wait/notify .但是,如果实施有限制(例如,如果这是家庭作业并且教授指定使用wait/notify),那么我将酌情编辑/删除我的答案。
【解决方案2】:

只需将您在 ThreadOne 中所做的复制到第二个。 线程旨在使程序的执行是并行的。

所以当你没有给它任何等待逻辑时,你不会期望第二个线程等待。

你应该使用线程二作为线程一的锁,线程一作为线程二的锁:

【讨论】:

  • 您能否更准确地说明应该用什么替换什么以及最重要的是为什么?
  • 使用Thread 对象作为锁定对象是一个糟糕的想法。
猜你喜欢
  • 1970-01-01
  • 2018-09-29
  • 2013-01-17
  • 1970-01-01
  • 2015-02-22
  • 2011-11-20
  • 2018-10-01
  • 1970-01-01
  • 2012-01-19
相关资源
最近更新 更多