2017-10-19 74 views
-1

信號我想用Java實現我自己的旗語(只是爲了練習,我知道,有Semaphore類) 我已經實現了它這樣的:我自己在java中

public class MySemaphore { 
    private int value = 1; 


    public synchronized void take() { 
     this.value++; 

     this.notify(); 
    } 

    public synchronized void release(){ 


     while (this.value == 0) { 
      try { 
       wait(); 
      } catch (InterruptedException e) { 
      } 
     } 

     this.value--; 
    } 

} 

我想使用它在這樣的線程:

public class MyThread extends Thread { 

    private static MySemaphore semaphore = new MySemaphore(); 
    public void run(){ 
     for (int i = 0; i < 100; i++) { 

      semaphore.take(); 
      try { 
       Main.myVariable += 1; 
       semaphore.release(); 
      } catch (Exception e){ 
       System.out.println("Exception" + e.getMessage()); 
      } 
     } 
    } 
} 

我開始和加入線程這樣的:

import java.util.ArrayList; 
import java.util.List; 

public class Main { 

    public static int myVariable = 0; 

    private static int threadsNumber = 100; 

    public static void main(String[] args) { 
     List<Thread> allThreads = new ArrayList<>(); 

     for (int i = 0; i < threadsNumber; i++) { 
      allThreads.add(new Thread(new MyThread())); 
     } 

     for (int i = 0; i < threadsNumber; i++) { 
      allThreads.get(i).start(); 
     } 

     for (int i = 0; i < threadsNumber; i++) { 
      try{ 
       allThreads.get(i).join(); 
      } catch (Exception e){ 
       System.out.println(e.getMessage()); 
       System.out.println("********************************"); 
      } 
     } 

     System.out.println("Result is " + myVariable); 

    } 
} 

我只是想增加一個變量10000次並收到結果。沒有信號量,結果小於10000(如9923,9684),這是由非增量原子性引起的。我想用信號量來保護這個變量。
不幸的是,結果仍然小於或等於10000(但更接近於9990以上的10個案例中的9個)。 你知道爲什麼會發生嗎?我的信號量是錯誤的還是在啓動線程時出錯?

+4

看來你得到了'take'和'release'混合起來。 'take'(第一次操作)必須等待,'release'必須通知。 – JimmyB

+0

你說得對,我交換了方法名稱,這很有效,我只是有很好的方法,但名稱錯了(接下來,我用它們不正確),謝謝。 – Dawid

+0

你嘗試過使用AtomicInteger嗎? – diginoise

回答

-1

在您的MySemaphore類中,值已經設置爲1.它應該爲零,因爲在您的發佈函數中您正在驗證值是否等於零。這意味着當你的程序啓動時,沒有線程能夠擁有信號量(因爲你已經設置爲1);這樣做,他們就會陷入等待狀態。當'threadsNumber'達到極限時,程序結束。換句話說,在程序結束之前,您沒有驗證任何線程是否處於等待狀態。這就解釋了爲什麼你有9/10的成功率。

我的建議是嘗試將值設置爲零,並驗證是否有任何線程處於等待狀態。

你的代碼是這樣的:

public class MySemaphore { 
    private int value = 0; //this is already an error in your code 

    public synchronized void take() { 
    this.value++; 
    this.notify(); // wakes up the first thread that called wait on the shared variable 
    } 

    public synchronized void release() throws InterruptedException{ 
    while(this.signals == 0) wait(); 
    this.value--; 
    } 

} 
+1

嘗試在'synchronized'塊之外使用'wait()'/ notify()'。報告結果。 – lukeg

+1

我正在使用synchronized,因爲信號量方法所做的操作不是原子的,我想讓它們如此。 – Dawid

+0

只需使用synchronized關鍵字即可實現自己的信號量。 –