2016-09-16 11 views
0

誰かがこのコードをコンパイルした後に、なぜ何かを待っているスレッドがあると思いますか? ID番号10,11,12のスレッドを1つずつ、50まで1つ増やしたい。 最終的には機能しますが、赤いボタン(終了)はまだ赤色です。つまり、まだプログラムが残っていますおそらく何かを待っています。指定されたスレッドでのJavaセマフォのインクリメント数

カウントが50の場合、リターンは動作し、メソッドから終了する必要があります。たぶんそれはありますが、十分ではありません。

public class App12 { 

    Semaphore sem1 = new Semaphore(1); 
    Semaphore sem2 = new Semaphore(0); 
    Semaphore sem3 = new Semaphore(0); 

    int count = 0; 

    public void inc() throws InterruptedException { 

     while (true) { 
      if (Thread.currentThread().getId() == 10) { 
       sem1.acquire(); 
       if (count != 50) { 
        count++; 
        System.out.println("Thread" + Thread.currentThread().getId() + " has incremented " + count); 

        sem2.release(); 
       } else 
        return; 
      } 

      if (Thread.currentThread().getId() == 11) { 
       sem2.acquire(); 
       if (count != 50) { 
        count++; 
        System.out.println("Thread" + Thread.currentThread().getId() + " has incremented " + count); 

        sem3.release(); 
       } else 
        return; 

      } 

      if (Thread.currentThread().getId() == 12) { 
       sem3.acquire(); 
       if (count != 50) { 
        count++; 
        System.out.println("Thread" + Thread.currentThread().getId() + " has incremented " + count); 

        sem1.release(); 
       } else 
        return; 

      } 
     } 
    } 

    public static void main(String[] args) { 

     App12 ap = new App12(); 
     for (int i = 0; i < 3; i++) { 
      Thread th1 = new Thread(new Runnable() { 
       public void run() { 
        try { 
         ap.inc(); 
         // dec3(); 

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

       } 
      }); 
      th1.start(); 

     } 
    } 
} 
+0

コンストラクタに渡されるパラメータの使い方はわかりますか? –

+0

ここでは、デフォルトのコンストラクタを使用しています。メソッドを静的に変更し、メソッドを呼び出すことができます。 – Victor

+0

しかし、私はコンストラクタからここを通過するものはありません。 – Victor

答えて

1

あなたの問題はあなたがスレッドでロックを解除したことがないということです、そして、彼らは永遠に待って終わる:

は、ここでは、コードです。あなたのロジックから

、あなたが50を打つ一度Bが戻っスレッド、しかしC.

を解除する解除を通します。スレッドBとCを解放しないでください。

したがって、必要なのは、他の待機スレッドをすべて解放する終了条件です。例えば

(あなたのwhileループで):

if(count == 50) { 
       sem2.release(); 
       sem3.release(); 
       sem1.release(); 
      } 

問題は、彼らがリリースされるのを待っているsemathorにロックした時点で、11または12インクリメント後、彼らはimmidiatelly再びループに入るということです。あなたの数が50だった場合、それを解放するスレッドはあなたのif条件に入ることなく戻ります。

また、else節にリリースを追加できるので、すべてのスレッドが解放されるはずです。

アルトゥル

EDIT、

を役に立てば幸い:

public class App12 { 

    Semaphore sem1 = new Semaphore(1); 
    Semaphore sem2 = new Semaphore(0); 
    Semaphore sem3 = new Semaphore(0); 

    int count = 0; 

    public void inc() throws InterruptedException { 

     while (true) { 

      if (Thread.currentThread().getId() == 10) { 
       sem1.acquire(); 
       if (count != 50) { 
        count++; 
        System.out.println("Thread " + Thread.currentThread().getId() + " has incremented " + count); 
        sem2.release(); 
       } else { 
        sem2.release(); 
        return; 
       } 
      } 

      if (Thread.currentThread().getId() == 11) { 
       sem2.acquire(); 
       if (count != 50) { 
        count++; 
        System.out.println("Thread " + Thread.currentThread().getId() + " has incremented " + count); 
        sem3.release(); 
       } else { 
        sem3.release(); 
        return; 
       } 

      } 

      if (Thread.currentThread().getId() == 12) { 
       sem3.acquire(); 
       if (count != 50) { 
        count++; 
        System.out.println("Thread " + Thread.currentThread().getId() + " has incremented " + count); 
        sem1.release(); 
       } else { 
        sem1.release(); 
        return; 
       } 
      } 

     } 
    } 

    public static void main(String[] args) { 

     App12 ap = new App12(); 
     for (int i = 0; i < 3; i++) { 
      Thread th1 = new Thread(new Runnable() { 
       public void run() { 
        try { 
         ap.inc(); 
         // dec3(); 
         System.out.println("Exist "); 
        } catch (InterruptedException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
        } 

       } 
      }); 
      th1.start(); 
     } 
    } 
} 

注:カウントが50になると、私はsemathorsをリリースしていますので、ここで修正実装とのあなたの完全なコードがあります他のスレッドは終了できます。

+0

私は理解しました。ありがとうございます:) – Victor

0

ロックを解除してスレッドを終了します。

import java.util.concurrent.Semaphore; 

public class App12 { 

Semaphore sem1 = new Semaphore(1); 
Semaphore sem2 = new Semaphore(0); 
Semaphore sem3 = new Semaphore(0); 


int count = 0; 

public void inc() throws InterruptedException { 

    while (true) { 

     if (Thread.currentThread().getId() == 10) { 
      sem1.acquire(); 
      if (count != 50) { 
       count++; 
       System.out.println("Thread" + Thread.currentThread().getId() + " has incremented " + count); 

      } else { 
       sem2.release(); 
       return; 
      } 
      sem2.release(); 

     } 

     if (Thread.currentThread().getId() == 11) { 
      sem2.acquire(); 
      if (count != 50) { 
       count++; 
       System.out.println("Thread" + Thread.currentThread().getId() + " has incremented " + count); 

      } else { 
       sem3.release(); 
       return; 
      } 
      sem3.release(); 
     } 

     if (Thread.currentThread().getId() == 12) { 
      sem3.acquire(); 
      if (count != 50) { 
       count++; 
       System.out.println("Thread" + Thread.currentThread().getId() + " has incremented " + count); 

      } else { 
       sem1.release(); 
       return; 
      } 
      sem1.release(); 

     } 

    } 

} 

public static void main(String[] args) { 

    App12 ap = new App12(); 

    for (int i = 0; i < 3; i++) { 
     Thread th= new Thread(new Runnable() { 
      public void run() { 
       try { 
        ap.inc(); 
        // dec3(); 

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

      } 
     }); 
     th.start(); 
    } 
} 
} 
+0

それは私のためだけです、私はスレッドを制御したいので、私は3つのセマフォを使用しています。しかし、ありがとう。 – Victor

+0

Tisは機能しません。彼は達成しようとしている論理を変えます。コードを見れば、彼が達成しようとしているのはスレッドを同期させて、それぞれがIN TURNカウンタをインクリメントすることです。あなたのソリューションでは、どのスレッドが次のインクリメントをしているかについての順序はありませんが、彼のロジックでは10,11,12,10,11,12となります。 – pandaadb

+0

コードが書き換えられました... – Krlos

関連する問題