【问题标题】:My own semaphore in java我自己的java信号量
【发布时间】:2017-10-19 15:46:19
【问题描述】:

我想用 Java 实现我自己的信号量(我知道,只是为了练习,有 Semaphore 类) 我是这样实现的:

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(但更接近,在 10 个案例中有 9 个大于 9990)。 你知道为什么会这样吗?我的信号量是错误的还是在启动线程时做错了什么?

【问题讨论】:

  • 您似乎把takerelease 搞混了。 take(第一次操作)必须等待,release必须通知。
  • 你说得对,我交换了方法名称,这很有效,我只是有好的方法,但名称错误(接下来是我使用不当),谢谢。
  • 您尝试使用AtomicInteger 吗?

标签: java multithreading semaphore


【解决方案1】:

在您的 MySemaphore 类中,value 已经设置为 1。它应该为零,因为在您的发布函数中,您正在验证 value 是否等于零。这意味着当您的程序启动时,没有线程能够拥有信号量(因为您已将其设置为 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--;
  }

}

【讨论】:

  • 尝试在synchronized 块之外使用wait()/notify()。报告结果。
  • 我正在使用同步,因为信号量方法所做的操作不是原子的,我想让它们如此。
  • 当您可以简单地使用同步关键字时,实现自己的信号量有什么意义。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-26
  • 1970-01-01
  • 2023-03-28
  • 1970-01-01
  • 2020-07-01
  • 1970-01-01
相关资源
最近更新 更多