2016-04-03 196 views
0

我剛剛開始學習Java中的多線程,並且仍在思考一些問題。首先,延伸Thread的類是否可以有其他與它關聯的實例方法,以便在其執行過程中調用 - 如果是,它是否可以在執行期間更改線程的狀態?其次,如果這個類被阻塞等待信號量,它的實例方法是否仍然可以被調用?就像這2個線程的東西運行:阻塞線程的調用方法

Thread1 t; 
public class Thread1 extends Thread { 
    private int num; 
    public run() { 
     sem.acquire(); // here it blocks waiting for another thread 
         //to call its setInt function and release it 
     System.out.println("num is " + num); 
    } 
    public void setInt(int i) { 
     num = i; 
    } 
} 

public class Thread2 extends Thread { 
    public run() { 
     t.setInt(5); 
     sem.release(); 
    } 
} 

回答

0

爲了證明你在找什麼,這裏是一個代碼示例至極我測試:

package test2; 

import java.util.concurrent.Semaphore; 

public class mainclass { 

    static Thread1 t; 

    static Semaphore sem; 

    static Semaphore sem_protect; 

    public synchronized static void main (String[] args) { 

     sem = new Semaphore(0); 

     sem_protect = new Semaphore(1); 

     t = new Thread1(); 

     Thread1 th1 = new Thread1(); 
     th1.start(); 

     Thread2 th2 = new Thread2(); 
     th2.start(); 

     try { 
      synchronized (th2){ 
      th2.wait(); 
      } 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     System.out.println("The end !"); 
     } 


    public static class Thread1 extends Thread { 

     private int num; 

     public void run() { 

      try { 
       sem.acquire(); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } // here it blocks waiting for another thread 
          //to call its setInt function and release it 
      try { 
       sem_protect.acquire(); 
       System.out.println("num is " + num); 
       sem_protect.release(); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 


     } 

     public synchronized void setInt(int i) { 

      try { 
       sem_protect.acquire(); 
       this.num = i; 
       sem_protect.release(); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 


      System.out.println("value of num is: "+num); 
     } 
    } 

    public static class Thread2 extends Thread { 
     public void run() { 
      t.setInt(5); 
      sem.release(); 
     } 
    } 

} 

下面是這段代碼的執行結果:

value of num is: 5 
The end ! 
num is 0 

有了這個結果,你可以看到你仍然可以從Thread2中訪問類thread1的方法。這意味着你訪問類實例的方法,線程沒有方法。 (這是你的第一個問題的答案)

第一個線程的狀態不會被第二個改變,num對於第一個線程仍然是0,線程每個都有自己的上下文。

即使我們用另一個信號保護對num的訪問,我們也沒有爲兩個線程設置相同的值num

3

這裏有一些混淆。

  1. 線程沒有方法。類有方法。
  2. 類不阻塞。線程被阻塞。
  3. 您可以隨時調用任何方法。該方法本身可能是同步的,這會延遲進入它,或者它可能在內部使用同步,同上或信號量,同上。