如何在一个类中处理多个线程?

线程通常以两种方式设计( 参见java教程 ):通过扩展Thread类或通过实现Runnable类。 无论哪种方式,您都需要指定在线程内运行的内容。

我设计了一个类,一个适用于在线资源的适配器,可以检索不同类型的信息。 该类由getInformationOfTypeA()和getInformationOfTypeB()等方法组成。 两者都包含连接到在线资源的代码,因此需要进行线程化以避免死锁。

问题是:我该如何设计呢? 我可以像下面这样做,但后来我只能实现一个方法:

public class OnlineResourceAdapter implements Runnable { public void run() { //get stuff from resource getInformationOfTypeA(); } public static void main(String args[]) { (new Thread(new OnlineResourceAdapter ())).start(); } public void getInformationOfTypeA(){ //get information of type A } public void getInformationOfTypeB(){ //get information of type B } } 

另一种方法是为每个方法创建单独的类,但这对我来说似乎不自然。

顺便说一句:我正在j2me开发我的应用程序

更新:

感谢您的回复,我认为最适合使用以下方法作为方法:

你觉得这怎么样:

 public class OnlineResourceAdapter{ public void getInformationOfTypeA(){ Thread t = new Thread(new Runnable() { public void run() { //do stuff here } }); t.start(); } public void getInformationOfTypeB(){ Thread t = new Thread(new Runnable() { public void run() { //do stuff here } }); t.start(); } } 

你觉得这怎么样?

听起来你应该有两个不同的类: InformationOfTypeAFetcherInformationOfTypeBFetcher ,每个类都应该实现Runnable 。 他们每个人都可以引用你的OnlineResourceAdapter (或类似的东西)的实例,但如果他们做了不同的事情,他们应该是不同的类。

两个匿名的内部课程,如ThorbjørnRavnAndersen上面隐约暗示的,有效。 这是一个代码示例:

 public class OnlineResourceAdapter { public final Runnable typeA; public final Runnable typeB; public OnlineResourceAdapter() { typeA = new Runnable() { public void run() { OnlineResourceAdapter.this.getInformationOfTypeA(); } }; typeB = new Runnable() { public void run() { OnlineResourceAdapter.this.getInformationOfTypeB(); // one can use a non-final typed variable // to store, which then<1> } }; } public static void main(String args[]) { OnlineResourceAdapter x = new OnlineResourceAdapter(); new Thread(x.typeA).start(); // start A new Thread(x.typeB).start(); // start B // <1>can be accessed here. } public void getInformationOfTypeA(){ // get information of type A // return the data or directly store in OnlineResourceAdapter. } public void getInformationOfTypeB(){ //get information of type B } } 

编辑:是的,你建议的方式是一个好方法。 您甚至可以将方法设为静态。 您可以使用“OnlineResourceAdapter.this”。 访问其他变量以存储结果。

为每个类创建一个基于Runnable的匿名类。 这将允许您在run()方法中执行您需要执行的操作。

我不明白为什么你不喜欢创建多个类的想法,考虑到Java不支持高阶函数,而代码的可变部分就是算法。

但是,如果您想要一个OnlineResourceAdapter实现,您可以使用策略模式并执行以下操作:

 public interface InformationGetter { public void getInformation(); } public class OnlineResourceAdapter implements Runnable { private final InformationGetter informationGetter; public OnlineResourceAdapter(InformationGetter i) { this.informationGetter = i; } public void run() { //get stuff from resource i.getInformation(); } } 

然后,您当然可以根据需要创建尽可能多的InformationGetter实现。

快来考虑一下,回顾一下这个方法, OnlineResourceAdapter现在并没有真正添加任何东西,除了使InformationGetter运行。 因此,除非你有一些令人信服的理由,否则我会说,只需让InformationGetter直接实现Runnable

许多人已经建议使用几个类的好方法。 由于您似乎更喜欢不需要多个类的方法,因此您可能还需要考虑使用构造函数来提供有关要获取的资源的信息:

 public class OnlineResourceAdapter implements Runnable { private string resourceType; public OnlineResourceAdapter(string resourceType) { this.resourceType = resourceType; } public void run() { if (resourceType.equals("A") { getInformationOfTypeA(); } else { // etc.. } } public void getInformationOfTypeA(){ //get information of type A } public void getInformationOfTypeB(){ //get information of type B } } 

用法:

 (new Thread(new OnlineResourceAdapter("A"))).start(); 

使用Callable类型的匿名类(与Runnable相反,它可以返回值)并使用Executor执行它们。 如果检索信息A和信息B的逻辑非常相似,那么您当然可以重构它并使用单个参数化内部类的Callables。

我不确定Callable和Executor是否是J2ME规范的一部分。 在标准Java中,无论如何我都会采用Proxy方法,并将外部资源封装为接口。

 public class AsyncMethodsTest { public class OnlineResourceAdapter { private final ExecutorService executor = Executors.newFixedThreadPool(2); public String getInformationOfTypeA() throws InterruptedException, ExecutionException, TimeoutException { Callable callable = new Callable() { @Override public String call() throws Exception { // Connect to external resource Thread.sleep(500); return "A"; } }; Future submit = executor.submit(callable); return submit.get(1000, TimeUnit.MILLISECONDS); } public String getInformationOfTypeB() throws InterruptedException, ExecutionException, TimeoutException { Callable callable = new Callable() { @Override public String call() throws Exception { // Connect to external resource Thread.sleep(1500); return "B"; } }; Future submit = executor.submit(callable); return submit.get(1000, TimeUnit.MILLISECONDS); } } @Test public void testMethodCalls() throws Exception { OnlineResourceAdapter adapter = new OnlineResourceAdapter(); assertNotNull(adapter.getInformationOfTypeA()); assertNotNull(adapter.getInformationOfTypeB()); } }