首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在同一个类中与Java并发运行2个方法

如何在同一个类中与Java并发运行2个方法
EN

Stack Overflow用户
提问于 2017-04-10 19:58:13
回答 4查看 16.4K关注 0票数 3

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

代码语言:javascript
复制
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?
    }
}

并在另一种方法中使用此方法:

代码语言:javascript
复制
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?

    }
}

注意:它们不需要同步。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-04-10 20:05:54

有几种方法可以完成你的任务。在线程不应该同步的情况下,您可以轻松地保持安静。

您可以使用来自Java并发的ExecutorService

代码语言:javascript
复制
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,否则应用程序不会停止,因为它会有活动的线程。

或者你可以使用香草Java线程的最简单的方法

代码语言:javascript
复制
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();
    
}

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

  • 如果已完成,请轮询Future
  • 等待Future完成。
  • 显式地等待特定的超时。

下面是一个示例:

代码语言:javascript
复制
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

票数 10
EN

Stack Overflow用户

发布于 2017-04-10 20:13:04

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

代码语言:javascript
复制
public class 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();
    }
}

您可以使用: results跟踪结果。

票数 1
EN

Stack Overflow用户

发布于 2021-05-29 21:58:08

使用Stream API的解决方案。

异步:

代码语言:javascript
复制
    public void runInParallel(Runnable... tasks) {
        Stream.of(tasks).map(Thread::new).forEach(Thread::start);
    }

同步:

代码语言:javascript
复制
    public void runInParallel(Runnable... tasks) {
        Stream.of(tasks).parallel().forEach(Runnable::run);
    }

使用方法:

代码语言:javascript
复制
    public void execute() {
        runInParallel(
                this::countA,
                this::countB);
    }

    public void executeWithParams() {
        runInParallel(
                () -> countA(5),
                () -> countA(10));
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43331960

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档