2017-04-10 136 views
2

我想在同一个类中使用2个方法并发使用Java中的相同对象。例如:如何在同一个类中使用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? 

    } 
} 

注:他们没有同步。

+2

什么阻止你这样做? – GhostCat

+0

@OusmaneMahyDiaw因为这两种方法不会同时运行。 – Andreas

+0

,因为它们在同一个对象的系统的不同部分中使用。此外,还有2种以上的方法,我不能只是一次性调用它们的方法。 –

回答

5

有几种方法可以实现你的任务在你试图同时运行的方法。当线程不应该同步时,你有安静的简单情况。

您可以使用ExecutorService从Java并发:

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

} 

为了让计算结果就可以得到Future<Integer>executorService,然后你有一个选择:

  • 调查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

值得注意的结果:当执行此操作时,类'aThread'不需要'extends Thread'。 – Andreas

+0

我该如何回顾这种方式的价值回报? –

+0

@EmreDanisan有几种方法来实现这一点。你可以从'submit'方法中获得'Future ',然后轮询它们或等待响应准备就绪。我会更新我的回答 –

-2

您需要创建的Runnable来调用独立的线程

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(); 
} 
+3

或者你可以使用lambda或者方法引用:'new Thread(myThread :: countA).start();' – Andreas

+2

或者你不能把你的线程包装到另一个线程中。 –

+1

值得注意的是:当执行此操作时,类“aThread”不需要“扩展Thread”。 – Andreas

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

}

您可以跟踪的结果:结果。

+0

您忘记了方法的结果 –

+0

您可以使用results来追踪结果。 –

相关问题