2017-10-19 119 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关键字即可实现自己的信号量。 –