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

时间:2010-01-17 16:51:31

标签: java multithreading java-me

线程通常以两种方式设计(see java tutorials):通过扩展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
  }

}

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

Btw:我正在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();
    }
}

你怎么看待这个?

6 个答案:

答案 0 :(得分:6)

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

答案 1 :(得分:4)

两个匿名的内部课程,如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”。访问其他变量以存储结果。

答案 2 :(得分:1)

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

答案 3 :(得分:1)

我不明白为什么你不喜欢创建多个类的想法,考虑到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

答案 4 :(得分:1)

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

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();

答案 5 :(得分:-1)

使用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<String> callable = new Callable<String>() {
                @Override
                public String call() throws Exception {
                    // Connect to external resource
                    Thread.sleep(500);
                    return "A";
                }

            };
            Future<String> submit = executor.submit(callable);
            return submit.get(1000, TimeUnit.MILLISECONDS);
        }

        public String getInformationOfTypeB() throws InterruptedException, ExecutionException,
                TimeoutException {
            Callable<String> callable = new Callable<String>() {
                @Override
                public String call() throws Exception {
                    // Connect to external resource
                    Thread.sleep(1500);
                    return "B";
                }

            };
            Future<String> 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());
    }
}