将单个可运行对象传递给多个线程构造函数

2022-09-04 01:09:52

如果我创建了一个可运行的对象

Runnable run = new MyRunnable();

然后将相同的对象传递给两个线程构造函数并运行它们

new Thread(run).start;
new Thread(run).start;
  1. 可能吗?这有什么影响?
  2. 如果我调用 Thread.sleep(0);在类 MyRunnable 中,两个线程会因为是同一个对象而休眠,还是线程实体与对象完全分离?
  3. 这样做是否有理由,如果不是,请仍然回答上面的两个问题,因为我认为我还没有完全理解线程机制?

答案 1
  1. 这绝对是可能的和合法的。如果你没有状态(没有字段),那么一切都会好起来的。如果您确实具有可变状态,则可能需要使用Java的许多互斥机制之一,例如 关键字。因为两个线程将改变同一对象的字段。RunnableRunnableReentrantLocksynchronizedRunnable

  2. 否,您创建并运行了两个不同的线程。他们只是简单地打电话给.Runnable.run()

  3. 这并非没有可能。我甚至不会说这必然是不好的做法。您可能这样做的特定情况留给读者作为练习...


答案 2
  1. 可能吗?这有什么影响?

是的,这是可能的。

这意味着 Runnable 中的任何状态(可能)都由所有线程共享,并且需要正确同步对该状态的访问/更新。

  1. 如果我调用 Thread.sleep(0);在类 MyRunnable 中,两个线程会因为是同一个对象而休眠,还是线程实体与对象完全分离?

不,他们不会。

线程在逻辑上与 .调用不会直接影响可能共享它的线程和其他线程。(它可能会间接影响其他线程;例如,如果一个线程在持有Runnable的原始锁时休眠,而其他线程需要获取锁才能取得进展。RunnableThread.sleep()Runnable

  1. 这样做是否有理由,如果不是,请仍然回答上面的两个问题,因为我认为我还没有完全理解线程机制?

如果没有与 关联的特定于线程的状态,并且您希望最大限度地减少空间开销或初始化对象的开销,则可以执行此操作。但是,这些开销很大的用例在实践中很少见。RunnableRunnable

在绝大多数实际用例中,每个线程无论如何都需要一个不同的实例......因为您需要告诉每个线程执行与其他线程不同的操作。Runnable