当前位置: 首页 > 面试题库 >

Java volatile变量无法正常运行。

那正初
2023-03-14
问题内容

public class MyThread
{
volatile static int i;

    public static class myT extends Thread
    {
        public void run ()
        {
            int j = 0;
            while(j<1000000){
                i++;
                j++;
            }
        }
    }

    public static void main (String[] argv)
    throws InterruptedException{
            i = 0;

            Thread my1 = new myT();
            Thread my2 = new myT();
            my1.start();
            my2.start();

            my1.join();
            my2.join();

            System.out.println("i = "+i);
    }
}

由于易失性构建发生在关系之前,因此i的最终值应严格为2000000。但是,实际结果与变量i不具有易失性没有什么不同。谁能解释为什么它在这里不起作用?由于我被声明为volatile,因此应该保护它免受内存不一致的影响。


问题答案:

谁能解释为什么它在这里不起作用?由于我被声明为volatile,因此应该保护它免受内存不一致的影响。

它受到保护,但不幸的i++是不是原子操作。它实际上是读取/递增/存储。因此,volatile这不会使您摆脱线程之间的竞争状况。您可能会从程序中获得以下操作顺序:

  1. 线程#1读取i,得到10
  2. 之后,线程#2读取i,得到10
  3. #1线程i增加到11
  4. 线程#2递增i到11
  5. 线程#1将11存储到 i
  6. 线程2将11存储到 i

如您所见,即使发生了2个增量,并且线程之间的值已正确同步,竞争条件也意味着该值仅增加了1。请看此美观的说明。这是另一个很好的答案:Java线程中的volatileint是安全的吗?

您应该使用的是AtomicInteger允许您从多个线程安全地递增的内容。

static final AtomicInteger i = new AtomicInteger(0);
...
        for (int j = 0; j<1000000; j++) {
            i.incrementAndGet();
        }


 类似资料:
  • 问题内容: 以下子组件从其父组件接收道具。然后,使用将道具设置为自己的状态,并使用将值渲染到相应的输入字段。 我用来在子组件收到新道具时更新其状态。 最初,调用该组件时,它可以正常工作。问题是第二次通过道具时发生的,触发道具通过的相应按钮需要两次单击才能设置孩子的状态。 我可能使用不正确? 完整代码: 问题答案: 我可能会错误地使用componentWillRecieveProps? 是的,因为您

  • 我使用ApacheStorm与Apache Kafka。使用的喷口是Kafka喷口,但它没有阅读Kafka主题的任何内容。我不知道这是否与我在暴风的工人中面临的问题有关。如果您知道任何相关解决方案,请告知我。 Storm拓扑已成功上载到Storm。我获取了日志,下面是工作人员在其文件:

  • 问题内容: 这正是我想要做的 我用表格打开一个页面,该表格包含有关用户的信息 我的getText()元素指示表中的用户数(例如“列表中的11个用户”) 我删除“列表中的用户”部分,并将字符串转换为整数,以便稍后在for循环中使用 我需要通过用户名(第9列)查找某些用户,并获取数字,该数字是该用户信息所在的行数(这就是我被卡住的地方) 我转到该行的第一列(该行将成为该特定用户的编辑按钮),然后单击它

  • 问题内容: 我创建了两个(即x1,y2),它们使用均匀分布进行了初始化,但是当我打印出结果时,它们不是我期望的。 这是我的代码: 结果如下: [6] [2] [0] 问题答案: 在您的代码中,和是随机数生成器。每次调用时,它们采用不同的值。因此,当您致电时,又依次致电您的数字生成器和,则没有理由获得与先前通话一致的结果。 为了实现您的期望,请将值存储在中: 另外,如果您不需要迭代之间的持久性,并且

  • 问题内容: 我有以下两个表 地块表 动作表 我想查找记录,但没有 这是我的查询 结果是 我要4号和5号包裹 问题答案: 请,在任何常用数据库产品中的AND运算符中都很难找到一个简单的错误。这里的问题不是数据库引擎没有产生正确的结果,而是您不了解AND运算符的作用。 看你的病情。将会发生的是,引擎将检查输出中的每个可能的行,并确定它是否满足您指定的条件。那么,对于第一行,采取的动作是否为“已接收”,

  • 问题内容: 我更改了使用.ajax方法而不是.load的实现,它在Firefox中可以正常工作,但在IE7或IE6中却不能: 为了达到目标,这已经使我丧命。 任何想法,我要去哪里错了? 问题答案: 我不小心弄清楚了问题所在。 此变量中引用的链接: 最后有一个哈希值,如下所示: 这会导致AJAX在IE的两个版本中掉落。 使用以下代码: 盖茨摆脱它,现在可以工作了:)