标签: happens-before

Java虚拟机如何实现“事前发生”内存模型?

Java的内存模型基于强制执行规则的“先有先后”关系,但也允许在缓存失效方面优化虚拟机的实现。

例如,在以下情况下:

// thread A
private void method() {
   //code before lock
   synchronized (lockA) {
       //code inside
   }
}

// thread B
private void method2() {
   //code before lock
   synchronized (lockA) {
       //code inside
   }
}

// thread B
private void method3() {
   //code before lock
   synchronized (lockB) {
       //code inside
   }
}
Run Code Online (Sandbox Code Playgroud)

如果线程A调用method()而线程B试图在lockA内部获取method2(),则同步lockA将要求线程B在释放其锁之前,观察线程A对所有变量所做的所有更改,甚至包括之前在“代码”中更改的变量。锁定”部分。

另一方面,method3()使用另一个锁并且不强制发生关系之前的事件。这为优化创造了机会。

我的问题是虚拟机如何实现那些复杂的语义?是否在不需要缓存时避免完全刷新缓存?

它如何跟踪在哪个点哪个线程更改了哪个变量,从而仅从内存加载所需的缓存行?

multithreading jvm memory-model happens-before vm-implementation

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

在第一次访问后,Java编译器是否合法省略getfield操作码?

我正在尝试一些C#代码的Java端口,我很惊讶地看到javac 1.8.0_60 getfield每次访问一个对象字段时都会发出操作码.

这是Java代码:

public class BigInteger
{
    private int[] bits;
    private int sign;

    //...

    public byte[] ToByteArray()
    {
        if (sign == 0)
        {
            return new byte[] { 0 };
        }

        byte highByte;
        int nonZeroDwordIndex = 0;
        int highDword;
        if (bits == null)
        {
            highByte = (byte)((sign < 0) ? 0xff : 0x00);
            highDword = sign;
        }
        else if (sign == -1)
        {
            highByte = (byte)0xff;
            assert bits.length > 0;
            assert bits[bits.length - 1] != 0;
            while …
Run Code Online (Sandbox Code Playgroud)

java jvm javac jls happens-before

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

如果线程A在java中的线程B之前启动,则A将在B之前由os调度?

我正在阅读"了解JVM高级功能和最佳实践",其中包含一个代码段,用于解释java中的先发制人规则.我不明白.代码如下:

private int value = 0;
//executed by Thread A
public void setValue(int value){
    this.value = value;
}
//executed by Thread B
public void getValue(){
    return value;
}
Run Code Online (Sandbox Code Playgroud)

假设A线程B在代码中的线程之前启动.我可以理解,我们不知道getValue()线程B 返回的结果,因为它不是线程安全的.但是,这本书说,如果添加的同步关键字的功能setValue()getValue(),那么就没有存在线程安全问题和方法getValue()将返回正确的值.这本书解释说,因为synchronized符合先前发生的规则.所以我在下面的代码中有两个问题.

public class VolatileDemo3 {
    private volatile int value = 0;
    public static void main(String[] args) {
        VolatileDemo3 v = new VolatileDemo3();
        Thread A = new Thread(v.new Test1());// Thread A
        Thread B = new Thread(v.new Test2());//Thread B …
Run Code Online (Sandbox Code Playgroud)

java multithreading happens-before

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

如何在请求处理线程和SocketChannel选择器线程之间建立一个before-before关系?

考虑请求 - 响应协议.

我们生成一个线程来执行一个select()循环,用于读取和写入已接受的非阻塞SocketChannel.这可能看起来像

while (!isStopped()) {
    selector.select();
    Iterator<SelectionKey> selectedKeys = selector.selectedKeys().iterator();

    while (selectedKeys.hasNext()) {
        SelectionKey selectedKey = selectedKeys.next();
        selectedKeys.remove();
        Context context = (Context) selectedKey.attachment();
        if (selectedKey.isReadable()) {
            context.readRequest();
        } else /* if (selectedKey.isWritable()) */ {
            context.writeResponse();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

where Context只是一个容器,用于相应的SocketChannel,一个缓冲区和逻辑来读入它并从中写入.在readRequest可能看起来像

public void readRequest() {
    // read all content
    socketChannel.read(requestBuffer);
    // not interested anymore
    selectionKey.interestOps(0);
    executorService.submit(() -> {
        // handle request with request buffer and prepare response
        responseBuffer.put(/* some response …
Run Code Online (Sandbox Code Playgroud)

java sockets multithreading nio happens-before

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

发生在Java内存模型中的规则之前

我目前正在攻读并发编程考试并且不明白为什么这个程序的输出是43.为什么x = y + 1之前执行t.start()?我还应该解释在我使用的规则之前发生了什么.

如果我理解程序顺序规则(一个线程中的每个动作发生 - 在该程序顺序后面的那个线程中的每个动作之前)t.start()都必须在执行之前执行,x = y + 1以便线程t复制变量x1.

public class HappensBefore {

static int x = 0;
static int y = 42;

public static void main(String[] args) {
    x = 1;
    Thread t = new Thread() {
        public void run() {
            y = x;
            System.out.println(y);
        };
    };
    t.start();
    x = y + 1;
}
Run Code Online (Sandbox Code Playgroud)

java concurrency multithreading java-memory-model happens-before

5
推荐指数
2
解决办法
395
查看次数

为什么“获取/发布”不能保证c ++ 11中的顺序一致性?

-Thread 1-                
y.store (20, memory_order_release); 
x.store (10, memory_order_release);

-Thread 2-
if (x.load(memory_order_acquire) == 10) {
  assert (y.load(memory_order_acquire) == 20);
  y.store (10, memory_order_release)
}

-Thread 3-
if (y.load(memory_order_acquire) == 10) {
  assert (x.load(memory_order_acquire) == 10);
}
Run Code Online (Sandbox Code Playgroud)

GCC Atomic Wiki的 “总体摘要”段落说?上面的代码assert(x.load(memory_order_acquire))可能会失败。但是我不明白为什么?

我的理解是?

  1. 线程3 由于获取障碍而无法LoadLoad重新排序。
  2. 由于发布障碍,Thread1无法对StoreStore重新排序。
  3. 当Thread2读取(x)-> 10时,必须将x从存储缓冲区刷新到Thread1中的缓存,因此每个线程都知道x的值已更改,例如使缓存行无效。
  4. Thread3使用Acquire屏障,因此可以看到x(10)。

c++ memory-model c++11 happens-before stdatomic

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

修改顺序是否有助于事前发生关系?

// Thread 1
// do A
x.store(1, std::memory_order_release); // operation1

// Thread 2
// do B
x.store(2, std::memory_order_release); // operation2

// Thread 3
x.load(std::memory_order_acquire); // operation3
Run Code Online (Sandbox Code Playgroud)

我知道,如果线程3读取线程1写入的值,则释放和获取操作将与同步,并且的效果A对线程3可见。
但是,如果是这样的话:

  • 的修改顺序x是1、2
  • 线程3读取线程2写入的值,因此2 发生在 3 之前

1和3之间是否存在事前关系?
还是本质上,修改顺序有助于事前发生关系?

c++ multithreading atomic c++11 happens-before

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

Java发生在之前和同步

我对Java的发生和同步有一些分歧.

想象一下以下场景:

主线程

MyObject o = new MyObject();    // (0)
synchronized (sharedMonitor) {
    // (1) add the object to a shared collection
}
// (2) spawn other threads
Run Code Online (Sandbox Code Playgroud)

其他主题

MyObject o;
synchronized (sharedMonitor) {
    // (3) retrieve the previously added object
}
// (4) actions to modify the object
Run Code Online (Sandbox Code Playgroud)

请注意,实例变量MyObject既不是volatile,也不是final.MyObject不使用同步的方法.

我的理解是:

  • 1 发生在 3 之前,因为在同一个监视器上有同步,而其他线程仅在2处生成,这在1之后执行.

  • 4上的操作无法保证以后对主线程可见,除非所有线程都进一步同步,并且主线程在这些操作之后以某种方式同步.

问:是否可以保证0处的操作可见,之前发生,3上的并发访问,或者我必须将变量声明为volatile? …

java multithreading synchronized happens-before

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

"部分订购"和发生在关系之前的java

我正在读以下的书

Java Concurrency in Practice http://www.informit.com/store/java-concurrency-in-practice-9780321349606

我对关于Happens-before关系的具体解释感到困惑.

它说,

操作按照之前发生的部分排序进行排序

"偏序"究竟是什么意思?

(书中有一个解释,但我不清楚)

java concurrency happens-before

4
推荐指数
2
解决办法
662
查看次数

Java - 之前发生 - 易变

我有以下代码

class VolatileCount {
    volatile int count;
    Object lock = new Object();

    public void increment() {

        synchronized (lock) {
            count = count + 1;
        }
        System.out.print(" " + count);
    }

}
Run Code Online (Sandbox Code Playgroud)

如果我increment()从多个线程调用相同的对象,我会得到以下输出(可能在您的机器上有所不同)

2 3 2 5 4 8 8 6 11 13 10 9 15 14 12 20 19
Run Code Online (Sandbox Code Playgroud)

看看我认为发生的重复数字似乎被破坏了,因为考虑前三个数字(2 3 2),如果线程看到3,则发生增量,并且因为变量是易变的,所以它的值应该是3或更多但是在任何线程中都不能为2.
但是,打印线似乎已在这里重新排序,重新排序该行是否正确?我在这里错过了什么?我运行JDK 7(Eclipse)

java multithreading java-memory-model happens-before

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