相关疑难解决方法(0)

为什么这个Java程序会终止,尽管显然它不应该(并没有)?

今天我实验室的敏感操作完全错了.电子显微镜上的执行器越过它的边界,在一系列事件之后,我损失了1200万美元的设备.我已将故障模块中的40K以上线路缩小到:

import java.util.*;

class A {
    static Point currentPos = new Point(1,2);
    static class Point {
        int x;
        int y;
        Point(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }
    public static void main(String[] args) {
        new Thread() {
            void f(Point p) {
                synchronized(this) {}
                if (p.x+1 != p.y) {
                    System.out.println(p.x+" "+p.y);
                    System.exit(1);
                }
            }
            @Override
            public void run() {
                while (currentPos == null);
                while (true)
                    f(currentPos);
            }
        }.start();
        while (true)
            currentPos = new Point(currentPos.x+1, currentPos.y+1);
    } …
Run Code Online (Sandbox Code Playgroud)

java concurrency java-memory-model memory-visibility

205
推荐指数
3
解决办法
5万
查看次数

同时访问公共领域.为什么可以观察到不一致的状态?

我正在阅读B. Goetz Java Concurrency在实践中,现在我正处于section 3.5安全的出版物中.他说:

// Unsafe publication
public Holder holder;
public void initialize() {
    holder = new Holder(42);
}
Run Code Online (Sandbox Code Playgroud)

这种不正确的发布可能允许另一个线程观察部分构造的对象.

我不明白为什么可以观察到部分构造的子对象.假设构造函数Holder(int)不允许this转义.因此,构造的引用只能由调用者观察到.现在,正如JLS 17.7所述:

无论是否将它们实现为32位或64位值,对引用的写入和读取始终是原子的.

线程不可能观察到部分构造的对象.

我哪里错了?

java multithreading

11
推荐指数
1
解决办法
447
查看次数

-XX:+ StressLCM,-XX:+ StressGCM JVM的选项

在玩一些jcstress代码时,我注意到两个对我来说很新的参数:StressLCMStressGCM

对我来说,要做的第一件事就是在源代码本身中搜索这些内容,尽管我发现了一些内容,但仍不清楚它们的实际作用。我真的很希望在源代码中看到一些注释,但这些注释可能会有所帮助,但是没有运气。

我还发现了在其中添加了这些错误的错误描述,但该解释对我而言毫无意义:

在LCM / GCM中随机化指令调度。

有人可以用简单的英语解释他们的工作吗?

java jvm jvm-hotspot java-12

10
推荐指数
1
解决办法
134
查看次数

使用锁保护非易失性字段的初始化?

出于教育目的,我正在编写一个简单的版本AtomicLong,其内部变量受到保护ReentrantReadWriteLock.这是一个简化的例子:

public class PlainSimpleAtomicLong {

  private long value;

  private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();

  public PlainSimpleAtomicLong(long initialValue) {
    this.value = initialValue;
  }

  public long get() {
    long result;

    rwLock.readLock().lock();
    result = value;
    rwLock.readLock().unlock();

    return result;
  }

  // incrementAndGet, decrementAndGet, etc. are guarded by rwLock.writeLock()
}
Run Code Online (Sandbox Code Playgroud)

我的问题:由于"value"是非易失性的,其他线程是否有可能通过不正确的初始值来观察PlainSimpleAtomicLong.get()?例如,线程T1创建L = new PlainSimpleAtomicLong(42)并与线程共享引用T2.为T2保证遵守L.get()为42?

如果没有,包装this.value = initialValue;到写锁定/解锁会有所作为吗?

java concurrency

6
推荐指数
1
解决办法
399
查看次数

当服务器VM是默认选项时,为什么有-server选项?

java命令的帮助菜单说该-server选项是选择"服务器"VM.它还声明'server'是默认选项.为什么这么多余?

编辑:

如果有任何帮助,"java -version"会产生:

java version "1.8.0_191"
Java(TM) SE Runtime Environment (buil 1.8.0_191-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.191-b12, mixed mode)
Run Code Online (Sandbox Code Playgroud)

java jvm

6
推荐指数
2
解决办法
522
查看次数

尽管没有代码明确泄漏,未初始化的对象泄露给另一个线程?

让我们看看这个简单的Java程序:

import java.util.*;

class A {
    static B b;
    static class B {
        int x;
        B(int x) {
            this.x = x;
        }
    }
    public static void main(String[] args) {
        new Thread() {
            void f(B q) {
                int x = q.x;
                if (x != 1) {
                    System.out.println(x);
                    System.exit(1);
                }
            }
            @Override
            public void run() {
                while (b == null);
                while (true) f(b);
            }
        }.start();
        for (int x = 0;;x++)
            b = new B(Math.max(x%2,1));
    }
}
Run Code Online (Sandbox Code Playgroud)

主线程

主线程创建的实例Bx设置为1,则该实例写入静态字段 …

java concurrency initialization memory-visibility

4
推荐指数
1
解决办法
945
查看次数

Java内存模型和最终字段

当我向JMM提出与“最终”相关的担保时,我最近感到困惑。这是JMM的摘录和示例

图4给出了一个示例,该示例演示了最终场与正常场的比较。类FinalFieldExample有一个最终整数字段x和一个非最终整数y。一个线程可以执行方法writer(),而另一个线程可以执行方法reader()。因为writer()在对象的构造函数完成之后写入f,所以将保证reader()可以看到fx的正确初始化值:它将读取值3。因此,不能保证reader()方法的值是4

class FinalFieldExample {
    final int x;
    int y;
    static FinalFieldExample f;

    public FinalFieldExample() {
      x = 3;
      y = 4;
    }

    static void writer() {
      f = new FinalFieldExample();
    }

    static void reader() {
      if (f != null) {
        int i = f.x; // guaranteed to see 3
        int j = f.y; // could see 0
      }
    }
}
Run Code Online (Sandbox Code Playgroud)

我的困惑是,对象'Obj'具有final和non-final字段是否已完全初始化并由线程'T'引用,T将仅看到final字段的正确值吗?构造后不会发生突变的非最终字段呢?我了解,如果在构造线程“ T”之后对其进行了突变,则可能看不到新值(除非该字段为volatile)。但是,如果该领域是非最终性和非易失性的,并且在构造之后没有发生变化,我该怎么办?

JVM如何实现与“最终”相关联的保证?例如,对于易失性,存在存储障碍。

java multithreading

1
推荐指数
1
解决办法
3641
查看次数