Java 将侦听器与线程一起使用

Java 将侦听器与线程一起使用,java,multithreading,thread-safety,listener,Java,Multithreading,Thread Safety,Listener,假设我有一个对象Foo,它希望通过使用侦听器接口的线程的多个运行实例获得通知。例如 界面: public interface ThreadListener { public void onNewData(String blabla); } Foo类: public class Foo implements ThreadListener { public Foo() { FooThread th1 = new FooThread(); FooThread th

假设我有一个对象Foo,它希望通过使用侦听器接口的线程的多个运行实例获得通知。例如

界面:

public interface ThreadListener {
   public void onNewData(String blabla);
}
Foo类:

public class Foo implements ThreadListener {
   public Foo() {
      FooThread th1 = new FooThread();
      FooThread th2 = new FooThread();
      ...

      th1.addListener(this);
      th2.addListener(this);
      ...

      th1.start();
      th2.start();
      ...
   }

   @Override
   public void onNewData(String blabla) {
     ...
   }
}
线程:

public FooThread extends Thread {
   private ThreadListener listener = null;

   public void addListener(ThreadListener listener) {
      this.listener = listener;
   }

   private void informListener() {
      if (listener != null) {
         listener.onNewData("Hello from " + this.getName());
      }
   }

   @Override
   public void run() {
     super.run();

     while(true) {
        informListener();
     }
   }
}
在最坏的情况下,多个线程同时调用onNewData(..)。Foo会怎么样?它是否会崩溃?

  • 您的
    Foo
    类没有状态(字段),因此除非它使用外部共享资源(例如文件…),否则它是线程安全的
  • 从构造函数启动线程通常是一个坏主意,尽管在无状态对象的情况下,我认为这是好主意
  • 如果
    onNewData
    不访问共享数据,它将按预期工作,如果访问,结果将取决于该方法的实现方式

这取决于
Foo
的实现。它是线程安全的吗?也就是说,
Foo
的实现是否存在任何数据竞争?是否要阻止它?还是仅仅是一个理论问题?onNewData可能会使JVM进程崩溃(我所知道的那种崩溃),例如,它会在内存中堆积所有字符串,或者在没有取消分配的情况下进行过多的内存分配。由于该方法在外部不是线程安全的,因此它可以覆盖从一个线程到另一个线程写入的数据。不要扩展
线程
。此外,让侦听器启动线程并将其自身添加到线程中是一种担忧丛林的迹象。将关注点分开。侦听器侦听,其他代码必须执行其余操作。首先,为什么不扩展线程?第二,您将如何按照您的建议分别实现侦听器和线程?Web上充满了为什么不扩展线程的解释。这是一个众所周知的反模式。一个参考是Josh Bloch的有效Java。@YannickWald