Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/extjs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 需要了解多线程环境中原子整数代码使用中的问题_Java_Atomicinteger - Fatal编程技术网

Java 需要了解多线程环境中原子整数代码使用中的问题

Java 需要了解多线程环境中原子整数代码使用中的问题,java,atomicinteger,Java,Atomicinteger,在一次采访中,有人向我提出了一个编码问题,我必须找出代码中的问题,并提出适当的解决方案 请在下面找到完整的代码: import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicInteger; public class Atomic { static AtomicInteger count = ne

在一次采访中,有人向我提出了一个编码问题,我必须找出代码中的问题,并提出适当的解决方案

请在下面找到完整的代码:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

public class Atomic {

    static AtomicInteger count = new AtomicInteger(0);
    static int counter = 0;

    public static class Runnable extends Thread {

    public void run() {
        while (count.getAndSet(1) != 0) {
            try {
                Thread.sleep(3000);
            } catch (Exception e) {

            }
        }
        counter = counter + 1;
        count.set(0);
    }

}

public static void main(String[] args) {
    ExecutorService executor = Executors.newFixedThreadPool(10);
    for (int i = 0; i < 10; i++) {
        Runnable runnable = new Runnable();
        executor.execute(runnable);
    }
    executor.shutdown();
}

}
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
导入java.util.concurrent.AtomicInteger;
公共级原子弹{
静态AtomicInteger计数=新的AtomicInteger(0);
静态整数计数器=0;
公共静态类Runnable扩展线程{
公开募捐{
while(count.getAndSet(1)!=0){
试一试{
睡眠(3000);
}捕获(例外e){
}
}
计数器=计数器+1;
计数集(0);
}
}
公共静态void main(字符串[]args){
ExecutorService executor=Executors.newFixedThreadPool(10);
对于(int i=0;i<10;i++){
Runnable Runnable=新的Runnable();
执行器。执行(可运行);
}
executor.shutdown();
}
}
这段代码运行正常。但问题是,若线程数量增加,或者若我运行For循环近10000次,这段代码就会出现一些问题


我试图找到问题,但找不到。

此代码有几处错误。你没有说“有一些问题”的意思,但这里有一些跳出的东西


首先,
计数器
变量没有安全更新。多线程不能保证最后写入值的可见性;也不能保证在读写之间没有其他线程更新其值

解决这个问题的简单方法是:将
计数器
更改为
原子整数
,然后使用
getAndIncrement
incrementAndGet
将其递增


其次,
公共静态类Runnable扩展线程{
非常可疑

  • 不要隐藏常见Java类的名称(这是隐藏
    Java.lang.Runnable
  • 不要直接扩展
    线程
    ,尤其是当您只需要一个
    java.lang.Runnable
    来添加带有
    执行器服务的execute时
  • 更合适的类声明是:

    public static class MyRunnable implements Runnable {
    
    (或者随便你怎么称呼它)

    或者您可以只声明一个匿名类:

    executor.execute(new Runnable() { /* body */ });
    
    或者您可以只声明一个lambda:

    executor.execute(() -> { /* body */ });
    

    第三,
    count
    在这里似乎并没有起到明显的作用

    • 如果“标志”为假:
    • 将“flag”设置为true
    • 增加一个变量
    • 将“flag”设置为false
    • 否则:
    • 等3秒钟
    • 再试一次
    count
    在这里扮演着“标志”的角色。它实际上只是一个
    AtomicBoolean

    但是,如果将
    计数器设置为
    原子整数
    ,则根本不需要单独的
    计数
    变量:

    while (true) {
      int current = counter.get();
      if (counter.compareAndSet(current, current + 1)) {
        // Nothing else is trying to update "current" at the same time:
        // we updated it. Stop.
        break;
      }
    
      // Something else is trying to update at the same time.
      // Sleep for 3 seconds.
      Thread.sleep(3000);
    }
    

    提示:如果两个线程试图同时递增
    计数器
    ,会发生什么情况?此代码中的一个非功能性问题是“
    公共静态类可运行扩展线程{
    ”。这是可行的,但哦,这真的不是一个好主意,至少有两种方式。