2014-10-05 53 views
2

讀取關於在網絡上,並與赫伯特·希本書幫助線程相當大的東西后,完整的Refernce Java的,我知道,暫停,恢復和停止多個實例上的線程和多線程的現代方式?

只同步防止多個線程在同一
實例同時執行的方法。我說...在同一個例子中。

當一個線程正在爲一個對象執行一個同步方法時,所有其他線程調用 同步對象塊的同步方法(掛起執行)直到第一個線程完成 與對象。注意...在同一個實例(對象)中。

第三,從Oracle文檔,
當一個同步方法退出時,它自動地建立與 一個之前發生的關係爲相同對象的同步方法的任何後續調用。這保證了對所有線程都可見的對象狀態的更改
。這也涉及使用多個線程處理同一個對象 。

但是,當情況出現多個線程在同一個類的不同實例上工作時,我總體感到困惑,無法確定發生了什麼以及發生了什麼?

考慮Herbert Schildt書中給出的例子:以現代方式暫停和恢復一個線程。

class NewThread implements Runnable { 

String name; // name of thread 
Thread t; 
boolean suspendFlag; 

NewThread(String threadname) { 
    name = threadname; 
    t = new Thread(this, name); 
    System.out.println("New thread: " + t); 
    suspendFlag = false; 
    t.start(); // Start the thread 
} 

// This is the entry point for thread. 
public void run() { 
    try { 
     for (int i = 15; i > 0; i--) { 
      System.out.println(name + ": " + i); 
      Thread.sleep(2000); 
      synchronized (this) { 
       while (suspendFlag) { 
        wait(); 
       } 
      } 
     } 
    } catch (InterruptedException e) { 
     System.out.println(name + " interrupted."); 
    } 
    System.out.println(name + " exiting."); 
} 

void mysuspend() { 
    suspendFlag = true; 
} 

synchronized void myresume() { 
    suspendFlag = false; 
    notify(); 
} 
} 

主線程:

class SuspendResume { 

public static void main(String args[]) { 

    NewThread ob1 = new NewThread("One"); 
    NewThread ob2 = new NewThread("Two"); 

    try { 
     Thread.sleep(10000); 
     ob1.mysuspend(); 
     System.out.println("Suspending thread One"); 

     Thread.sleep(10000); 
     ob1.myresume(); 
     System.out.println("Resuming thread One"); 

     ob2.mysuspend(); 
     System.out.println("Suspending thread Two"); 
     Thread.sleep(10000); 

     ob2.myresume(); 
     System.out.println("Resuming thread Two"); 
    } catch (InterruptedException e) { 
     System.out.println("Main thread Interrupted"); 
    } 
    // wait for threads to finish 
    try { 
     System.out.println("Waiting for threads to finish."); 
     ob1.t.join(); 
     ob2.t.join(); 
    } catch (InterruptedException e) { 
     System.out.println("Main thread Interrupted"); 
    } 

    System.out.println("Main thread exiting."); 
} 

} 

輸出如下:

New thread: Thread[One,5,main] 
New thread: Thread[Two,5,main] 
One: 15 
Two: 15 
One: 14 
Two: 14 
Two: 13 
One: 13 
Two: 12 
One: 12 
Two: 11 
One: 11 
Suspending thread One 
Two: 10 
Two: 9 
Two: 8 
Two: 7 
Two: 6 
Resuming thread One 
Suspending thread Two 
One: 10 
One: 9 
One: 8 
One: 7 
One: 6 
Resuming thread Two 
Waiting for threads to finish. 
Two: 5 
One: 5 
Two: 4 
One: 4 
Two: 3 
One: 3 
Two: 2 
One: 2 
Two: 1 
One: 1 
Two exiting. 
One exiting. 
Main thread exiting. 

我的理解: 有3個線程。除主線程以外,2個正在處理同一類的兩個實例。

主線程進入睡眠10秒。 在這段時間內,另外2個人可以通過for循環做5次(因爲他們每次都睡2秒) 在這段時間內,標誌是錯誤的,因此他們沒有去while loop.O/p在此間隔期間是:

One: 15 
Two: 15 
One: 14 
Two: 14 
Two: 13 
One: 13 
Two: 12 
One: 12 
Two: 11 
One: 11 

主線程喚醒。

ob1將其稱爲mysuspend(),它將suspendFlag更改爲true。 這裏感到困惑:線程工作ob1會考慮這個改變。

懸掛線程一//獲得打印。

主線程再次進入睡眠狀態10秒。 在ob1上工作的線程沒有產生任何輸出。爲什麼? (因爲前面提到的變化已經考慮到了,所以在通過循環之後,wait()會掛起這個線程,我正確嗎?)。

Two: 10 
Two: 9 
Two: 8 
Two: 7 
Two: 6 

OB1調用同步方法:myresume()內其它改變

suspendFlag爲false和

發出通知()//通知給其他線程的其它物體上工作。 我知道肯定一個通知命令從等待集中任意選擇一個線程並將其標記爲最終復活。鎖仍然是它。

困惑在這裏:如何爲線程(在OB1)能夠自我復活(我的意思是如何通過只是改變即使我不是太清楚它是怎麼懸掛的標誌來)

恢復線程都有一個/ /打印。 線程被清楚地復活(恢復),因爲o/p在那裏,如下所示。

One: 10 
One: 9 
One: 8 
One: 7 
One: 6 

在同一時間,另一個線程被暫停,同樣的事情發生。

還有一個問題:

當一個線程正在執行的對象同步的方法,確實直到第一線程與對象做來調用同步對於其他對象塊(暫停執行)方法所有其他線程。我說了另一個對象?

+0

我不太瞭解Java或其線程要求,但我希望'void mysuspend()'方法也需要同步。 – 2014-10-05 17:45:49

回答

1

ob1將其稱爲mysuspend(),它將suspendFlag更改爲true。困惑在這裏:線程 工作ob1將考慮這種變化。

主線程再次進入睡眠狀態10秒。在ob1上工作的線程沒有產生任何輸出。爲什麼? (因爲前面提到的 已經考慮到了,所以在通過循環去 之後,wait()掛起了這個線程,我是否正確?)。

是的。由於可運行實例'ob1'state已更改,並且僅影響在可運行實例'ob1'上工作的線程。

發出notify()//通知給另一個對象的另一個線程。

號的java.lang.Object.notify()醒來是對象監視器上等待的單個線程。請注意關鍵字這個。由於ob1只有一個線程作用於其上,所以發佈wait()的線程將被通知,而不是線程在ob2上工作,它們是兩個different threads工作於相同類型的two different runnable instances

怎麼樣線程(在OB1)能夠自我復活(我的意思是如何通過只是改變即使我不是太清楚如何到達 懸掛國旗來。)

勢必ob1可以監控的ob1的狀態的變化的線程。綁定到ob2的線程可以監視ob2狀態的更改。

當一個線程正在執行同步方法的對象,是否調用用於其他 對象塊同步方法(暫停執行),直到第一線程與 對象完成所有其它線程。我說了另一個對象?

不可以。只有在特定實例上工作的線程會受到影響。如果你想這樣的事情發生,

NewThread obj = new NewThread(); // single runnable instance 
Thread ob1 = new Thread(obj); // two different threads sharing the same instance 
Thread ob2 = new Thread(obj); 

這樣線程ob1ob2可以共享使用的objwait()notify()方法obj實例和communicate彼此。

如果您正在尋找跨實例的同步線程,請查看:this