2017-04-10 134 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來追蹤結果。 –

相關問題