在线程和对象创建上

时间:2012-01-09 17:50:49

标签: java multithreading

假设您有一个具有构造函数的类MyClass

public Myclass(SomeObject o)

Myclass,还有方法public void doSomethingCleverWith(String s)

我希望将MyClass作为Thread执行,所以我

Thread t = new Thread(new MyClass(SomeObject));

执行此线程时,run需要调用doSomethingCleverWith(String)。然而,运行(据我所知)并没有接受任何参数。

你怎么建议我处理这个? String应该是MyClass构造函数的一部分吗?我能以某种方式做别的事吗?

4 个答案:

答案 0 :(得分:4)

您不在线程上执行对象 - 您在线程上执行代码 ...由run()方法指定的代码你传递给Thread构造函数的runnable,假设你是这样做的。

你要做的事情并不是很清楚,但听起来你可能需要将额外的信息(字符串)传递给MyClass的构造函数......或以不同的方式执行,例如:

final MyClass tmp = new MyClass(SomeObject));
Thread t = new Thread(new Runnable() {
    @Override public void run() {
        tmp.doSomethingCleverWithString(someValueHere);
    }
});

如果您澄清了您想要实现的目标,我们可以为您提供更多帮助。

答案 1 :(得分:1)

鉴于上述情况,我会MyClass实施Runnable,并将SomeObject作为构造参数来填充字段。

然后,run()的实现将使用该字段作为参数调用您的类。

不要忘记在start()顺便说一句,而不是Thread拨打run()

答案 2 :(得分:1)

您可以使用Builder Pattern来确保正确构造MyClass个对象,或者您怀疑的简单依赖注入(将String传递给MyClass构造函数) 。

答案 3 :(得分:0)

这取决于MyClass的预期生命周期。如果你有一种情况,MyClass(SomeObject)应该在其生命过程中对多个不同的字符串进行操作,那么你可以通过某种方法而不是在构造函数中将String实例交给它来避免额外的对象构造。

如果MyClass(SomeObject)只会对一个String进行操作,那么你应该在构造过程中传入String(或者你可以在启动MyClass之前通过另一个方法传递它,如果MyClass的创建应该与它分开使用)。

假设您希望每个MyClass实例处理多个字符串,并且单独线程的原因仅用于异步处理,那么我将使用BlockingQueue实现来创建一个异步处理请求的单个线程(使用单独的AsyncProcessor,包装我现有的同步处理器)。例如:

public interface StringProcessor
{
  public void processString(String string);
}

public class AsyncProcessor implements StringProcessor
{
  private final ArrayBlockingQueue<String> queue;
  private final StringProcessor immediateProcessor;

  private AsyncProcessor(StringProcessor immediateProcessor, int maxQueue)
  {
    this.queue = new ArrayBlockingQueue(maxQueue);
    this.immediateProcessor = immediateProcessor;
    Thread thread = new Thread(new ProcessingTask());
    thread.start();
  }

  // Add string to queue for asynchronous processing later.
  public void processString(String string)
  {
    queue.offer(string);
    // Handle / log insert failure (queue full, maybe throw an Exception)
  }

  private class ProcessingTask implements Runnable
  {

    public volatile boolean running = true;

    public void run()
    {
      while(running)
      {
        // Probably need to deal with InterruptedException here...
        immediateProcessor.processString(queue.take());
      }
    }
  }
}

public class MyProcessor implements StringProcessor
{
  private final SomeObject someObject;

  public MyProcessor(SomeObject someObject)
  {
    this.someObject = someObject;
  }

  public void processString(String string)
  {
    // Process the string...
  }
}

public static void main(String[] args)
{
  SomeObject myObject = new SomeObject();
  StringProcessor myProcessor = new MyProcessor(SomeObject myObject);
  StringProcessor asyncProcessor = new AsyncProcessor(myProcessor,100);

  asyncProcessor.processString("This string will be processed asynchronously");
}