2017-05-07 110 views
0

據說如果一個類實現了Runnabe接口,它可以變成一個線程,它的實例可以共享類中的同一個數據區。但是,Runnable接口中只有run()方法,那麼它是如何實現的呢?在JAVA多線程中共享相同的數據區域?

+0

加上'實現Runnable'你的類中,實現'運行()'方法,從那裏 –

回答

0

@La凱特,分享發生在一個具體的類implements Runnable。這樣的類將具有狀態,即,保存關於Runnable實例的信息的字段。這些字段在使用完全相同的Runnable實例的每個線程之間共享。這與錯誤的extends Thread習語不同,每個線程都有其獨立的狀態。

因此,例如:

final Runnable runnable = new Runnable() { 
    final Object lock = new Object(); 

    final ImportantInfo info = new ImportantInfo(); 

    @Override 
    public void run() { 
    while (true) { 
     doABunchOfStuff(); 
     synchronized (lock) { 
      info.load(); 
     } 
     doABunchOfOtherStuff(); 
    } 
    } 
}; 

Runnable實例可以被髮送到一個以上的Thread

Thread footh = new Thread(runnable); 
Thread barth = new Thread(runnable); 
footh.start(); 
barth.start(); 

兩個線程使用完全相同的Runnable,所以這意味着每個線程現在股狀態通過不可變的lock對象和可變的info對象。前者可以同步訪問,後者可以在線程之間傳遞更改。

-1

事實上,Runnable接口只提供了一種將對象轉變爲線程的方法(它是一個接口),它不是共享變量的結構,這些對象可以使用「synchronized」修飾符或其他線程安全結構共享變量(你可以在oracle指南中找到它),但這取決於你。

+0

訪問您的實例字段這並未」請在這裏解釋實例如何共享數據,正如OP所要求的。 –

0

但是,在Runnable接口中只有run()方法,那麼 如何實現呢?

這是通過在你的runnables中引入狀態然後傳遞這些狀態對象的相同實例來實現的。沒有狀態的可運行程序不共享數據。

下面不是一個正在運行或編譯的代碼,只是給你一個大概的想法 - 有兩個線程共享一個Student對象。 private Student student;將狀態引入您的可運行。

public class ExampleRunnable implements Runnable { 

    private Student student; 
    public void ExampleRunnable(Student student){ 
    this.student=student; 
    } 

    @Override 
    public void run(){ 
    .....do something with student here in synchronized way.... 
    ..... 
    } 

以下是創建線程類,

public class MainClass { 
     public static void main(String[] args){ 
     Student student = new Student(); 

     Thread thread1 = new Thread(new ExampleRunnable(student)); 
     Thread thread2 = new Thread(new ExampleRunnable(student)); 

     /* So in above code, there are two different runnables and two different threads but both are using same Student object . This way you can share data among various runnables/threads. */ 
    } 
    } 
     } 
+0

'ExampleRunnable#student'應該是'final',並且可以共享'Runnable'實例本身。 –