具有返回值的对象内的java线程方法

时间:2015-07-21 12:55:01

标签: java multithreading methods

我是使用多线程的新手,但我想异步调用一个方法(在一个单独的Thread中),而不是同步调用它。基本的想法是我在内存中创建一个带有对象的套接字服务器,因此对于每个客户端,我将不得不异步运行object.getStuff()之类的内容。

我发现的两个结构是:

  1. 让类实现Runnable和线程this
  2. 在方法中声明runnable类。
  3. 此外this方法需要返回值 - 是否需要使用ExecutorCallable来实现此目的?有人能指出我正确的方向来实现这个吗?

    我已经尝试了实现选项2,但这似乎并不是同时处理:

    public class Test {
        private ExecutorService exec = Executors.newFixedThreadPool(10);
    
        public Thing getStuff(){
    
            class Getter implements Callable<Thing>{
                public Thing call(){
                    //do collection stuff
                    return Thing;
                }
            }
    
            Callable<Thing> callable = new Getter();
            Future<Thing> future = exec.submit(callable);
            return future.get();   
        }    
    }
    

    我正在为服务器实例化一个测试对象,并为每个客户端连接调用getStuff()。

4 个答案:

答案 0 :(得分:2)

线程教程

关于并发的Java教程有一个很好的部分。它在https://docs.oracle.com/javase/tutorial/essential/concurrency/runthread.html。从本质上讲,您可以实施RunnableCallable,也可以继承Thread

子类化线程

您可以编写一个扩展Thread的类,包括一个匿名内部类。实例化它,然后调用start()方法。

public class MyThread extends Thread {
  public void run() {
    System.out.println("This is a thread");
  }
  public static void main(String[] args) {
    MyThread m = new MyThread();
    m.start();
  }
}

实施Runnable

您可以编写一个实现Runnable的类,然后将实例包装在Thread中并调用start()。非常像以前的。

public class MyRunnable implements Runnable {
  public void run() {
    System.out.println("This is a thread");
  }
  public static void main(String[] args) {
    MyRunnable r = new MyRunnable();
    (new Thread(r)).start();
  }
}

返回值

Runnable不允许返回值。如果您需要,则需要实现CallableCallable看起来很像Runnable,除非您覆盖call()方法而不是run()方法,并且您需要将其提供给ExecutorService。< / p>

public class MyCallable implements Callable<Integer> {
  public Integer call() {
    System.out.println("A thread using Callable<Integer>");
    return 42;
  }
  public static void main(String[] args) {
    MyCallable c = new MyCallable();
    Future<Integer> f = Executors.newSingleThreadExecutor().submit(c));
    System.out.println("The thread returned: " +
      f.get());
  }
}

答案 1 :(得分:1)

  

我发现的两个结构是1)让类实现Runnable并线程化'this'和2)在方法中声明一个runnable类。

选项(2)可能更好。如果他们有更多类,那么大多数程序都会得到改进,而不是更少。程序中的每个命名实体 - 每个包,类,方法,等等 - 应该只有一个责任。在您的选项(1)中,您要求班级做两个事情。

对于您的选项(2),您实际上不必声明整个班级。您可以使用匿名内部类,或者如果您可以一直使用Java8,则可以使用 lambda表达式。谷歌让任何一方了解更多。

  

此外,此方法需要返回值。

经典的方法是让Runnable对象在线程终止之前通过其自己的一个字段返回值。然后父线程可以检查对象并在之后获得返回值。

  

是否有必要使用Executor和Callable来实现这一目标?

必要吗?很多人认为ExecutorService Good Thing。

听起来您正在创建一个为多个客户端提供服务的服务器。这些客户端是否不断连接和断开连接?使用线程池(即ThreadPoolExecutor)的优点是它可以使您的程序不再持续创建和销毁线程(例如,每次客户端连接/断开连接时)。创建和销毁线程非常昂贵。如果你有很多客户端连接和断开连接,那么使用线程池可能会对服务器的性能产生很大的影响。

答案 2 :(得分:0)

自己创建和管理线程通常是不好的方法。 正如您已经指出的那样 - 使用Executors实用程序类来创建执行程序并向其提交Callable

答案 3 :(得分:0)

public class RunWResult implements Runable{
    private volatile ResultType var;

    //the thread method
    public void run(){
        ...

        //generate a result and save it to var
        var = someResult();

        //notify waiting threads that a result has been generated
        synchronized(this){
            notify();
        }
    }

    public ResultType runWithResult(){
        //run the thread generating a result
        Thread t = new Thread(this);
        t.start();

        //wait for t to create a result
        try{
            wait();
        }catch(InterruptedException e){}

        //return the result
        return var;
    }
}