如何使用Java在同一个类中同时运行2个方法

时间:2017-04-10 19:58:13

标签: java multithreading concurrency

我想在Java中使用同一个对象同时在同一个类中使用2个方法。例如:

public class aThread extends Thread {

    int countA = 0;
    int countB = 0;

    int countA(){
        for (int i = 0; i < 1000; i++) {
            countA++;
        }
        return countA;
    }
    int countB(){
        for (int i = 0; i < 1000; i++) {
            countB++;
        }
        return countB;
    }
    @Override
    public void run() {
        super.run(); 
        //should there be something here?
    }
}

在另一种方法中使用这种方法:

public class MainClass {

    public static void main(String[] args) {

        aThread myThread = new aThread();

        myThread.countA(); //I want these 2 methods to run concurrently.
        myThread.countB();
        //how do I use myThread.start() here?

    }
}

注意:它们不必同步。

4 个答案:

答案 0 :(得分:6)

有几种方法可以完成您的任务。当线程不应该同步时,你可以很安静。

您可以使用Java Concurrency中的ExecutorService

public class ConcurrentCode {

    private int countA = 0;
    private int countB = 0;

    int countA(){
        for (int i = 0; i < 1000; i++) {
            countA++;
        }
        System.out.println(countA);
        return countA;
    }

    int countB(){
        for (int i = 0; i < 1000; i++) {
            countB++;
        }
        System.out.println(countB);
        return countB;
    }

    public void execute(){
        ExecutorService executorService = Executors.newFixedThreadPool(2);

        // method reference introduced in Java 8
        executorService.submit(this::countA);
        executorService.submit(this::countB);

        // close executorService
        executorService.shutdown();
    }


    public static void main(String[] args){
        new ConcurrentCode().execute();
    }

}

请记得关闭ExecutorService,否则您的应用程序将无法停止,因为它将具有活动线程。

或者您可以使用vanilla Java threads获得最简单的方法:

public void executeInNativeThreads(){

    // starts new thread and executes countA in it
    new Thread(this::countA).start();

    // starts new thread and executes countB in it
    new Thread(this::countB).start();

}

要获得计算结果,您可以从executorService获取Future<Integer>,然后您可以选择:

  • 轮询Future如果已完成
  • 等到Future完成。
  • 明确等待某段时间

以下是一个例子:

public void execute() throws Exception {
    ExecutorService executorService = Executors.newFixedThreadPool(2);

    Future<Integer> future1 = executorService.submit(this::countA);
    Future<Integer> future2 = executorService.submit(this::countB);

    // wait until result will be ready
    Integer result1 = future1.get();

    // wait only certain timeout otherwise throw an exception
    Integer result2 = future2.get(1, TimeUnit.SECONDS);

    System.out.println("result1 = " + result1);
    System.out.println("result2 = " + result2);

    executorService.shutdown();
}

注意,当我们明确等待future1的结果时,future2仍然在另一个线程中执行。这意味着特别是在这个例子中,future2的计算不会有大的延迟。

另外,请查看异步计算中使用的CompletionStage

答案 1 :(得分:1)

要同时运行代码,至少需要两个线程:

公共类MyClass {

    int countA = 0;
    int countB = 0;

    public int countA(){
        for (int i = 0; i < 1000; i++) {
            countA++;
        }
        return countA;
    }
    public int countB(){
        for (int i = 0; i < 1000; i++) {
            countB++;
        }
        return countB;
    }



public static void main(String[] args) throws Exception{
    MyClass myClass = new MyClass() ;
    ExecutorService  executorService = Executors.newFixedThreadPool(2) ;
    List<Callable<Integer>> tasks = new ArrayList<Callable<Integer>>() ;
    tasks.add(myClass::countA) ;
    tasks.add(myClass::countB) ;
    List<Future<Integer>> results = executorService.invokeAll(tasks) ;
    System.out.println(results.get(0).get()+" "+results.get(1).get());
    executorService.shutdown();
}

}

您可以使用以下结果跟踪结果:

答案 2 :(得分:0)

使用 Stream API 的解决方案。

异步:

    public void runInParallel(Runnable... tasks) {
        Stream.of(tasks).map(Thread::new).forEach(Thread::start);
    }

同步:

    public void runInParallel(Runnable... tasks) {
        Stream.of(tasks).parallel().forEach(Runnable::run);
    }

使用方法:

    public void execute() {
        runInParallel(
                this::countA,
                this::countB);
    }

    public void executeWithParams() {
        runInParallel(
                () -> countA(5),
                () -> countA(10));
    }

答案 3 :(得分:-2)

您需要创建Runnables以调用您尝试在独立线程中并发运行的方法

public static void main(String[] args) {
  final aThread myThread = new aThread();

  Runnable a = new Runnable() {
    public void run() {
      myThread.countA();
    }
  });
  Runnable b = new Runnable() {
    public void run() {
      myThread.countB();
    }
  });
    new Thread(a).start();
    new Thread(b).start();
}