假设您有一个具有构造函数的类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
构造函数的一部分吗?我能以某种方式做别的事吗?
答案 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");
}