【问题标题】:Synchronized method not blocking other threads [closed]同步方法不阻塞其他线程[关闭]
【发布时间】:2016-05-11 18:38:39
【问题描述】:

我有一个像这样的单例类:

private static StringsHandler INSTANCE = null;
private int count = 0;
//I have 2 methods so I don't have to be sending/checking nulls on getInstance
//once it's created
public static void createInstance(List<String> strings){
    if(StringsHandler.INSTANCE == null)
        StringsHandler.INSTANCE = new StringsHandler(strings);
}

public static StringsHandler getInstance(){
    return StringsHandler.INSTANCE;
}

public synchronized File use(){
    count++;
    System.out.println("threads using .use " + count);
    while(true){} //Keep the thread here so count should stay as 1
}

在应用主类上创建实例,main方法如下:

if(stringList.isEmpty()){
        LOGGER.error("List was empty");
        System.exit(0);
    }
StringsHandler.createInstance(stringList);

我这样称呼它:

list.parallelStream().forEach(element -> {
    SingletonClass.getInstance().use();
});

这应该打印threads using .use 1,但它打印threads using .use 5 为什么同步关键字允许超过1个线程?

【问题讨论】:

  • 你有多个对象吗?
  • 这个怎么称呼?
  • 编辑回答您的问题
  • 发布简短但完整的示例,让我们重现您的问题SSCCE / MCVE。不要让我们猜测什么出了问题,即使我们猜测猜测和正确解释为什么部分的可能性较低,这可能会阻止我们提出正确的解决方案。
  • MCVE 意味着我们应该能够复制代码并将其粘贴到文件中,然后编译并运行它。由于这不是 MCVE,因此投票关闭。

标签: java multithreading java-8 synchronized java-threads


【解决方案1】:

synchronized 关键字只允许一个线程锁定使用它的特定对象。因此,如果您有多个此对象的实例,并且一次对多个实例调用 use,它们将能够同时执行。

您有责任决定并始终如一地执行数据元素与排除方法的映射。如果不止一种排除方法保护同一个数据元素,那么您将无法获得正确的排除。

【讨论】:

  • 忘了提到我使用的是单例类,已编辑问题。
  • 将对象标识符记录到use,你会发现它们不是同一个对象。
  • 只要count未被声明为static,就不应该有任何线程打印5的值。除非有其他代码在操作变量……
  • 其实比这复杂一点,它确实打印了一个不同于1的数字,但它只打印一次。
  • @ArtemioRamirez,听起来问题在于您没有向我们展示的代码。
猜你喜欢
  • 1970-01-01
  • 2017-02-28
  • 1970-01-01
  • 2014-04-03
  • 2013-07-11
  • 1970-01-01
  • 1970-01-01
  • 2017-08-13
  • 1970-01-01
相关资源
最近更新 更多