java同步操作_Java:同步操作究竟与波动有关吗?

对不起,这是一个很长的问题.

我最近在多线程中进行了大量的研究,因为我慢慢地将其纳入个人项目.然而,可能由于大量略有不正确的示例,在某些情况下使用同步块和波动对我来说仍然不清楚.

我的核心问题是:当线程在同步块内时,对引用和原语的更改会自动发生变化(即,在主内存而不是高速缓存上执行),或者读取也必须同步才能工作正常吗?

>如果是,同步一个简单的getter方法的目的是什么? (见示例1)此外,只要线程在任何东西上同步,都将发送到主内存的所有更改?例如,如果它被发送到一个非常高级别的同步处理工作的负载,那么每一次的改变都会变成主内存,没有什么可以缓存,直到它再次解锁?

>如果不是,必须在同步块内显式地进行更改,或者java实际上是否可以使用Lock对象? (见实施例3)

>如果同步对象需要与以任何方式更改的引用/原语相关(例如,包含它的直接对象)?我可以通过在一个对象上同步来写,如果否则安全吗? (见实施例2)

(请注意以下示例,我知道同步方法和同步(这)被皱眉和为什么,但是讨论超出了我的问题的范围)

示例1:

class Counter{

int count = 0;

public synchronized void increment(){

count++;

}

public int getCount(){

return count;

}

}

在这个例子中,increment()需要同步,因为不是一个原子操作.因此,同时增加的两个线程可能导致整数增加1到计数.计数原语需要是原子的(例如不长/双/引用),这样就好了.

getCount()需要在这里同步吗?为什么?我听到的最多的解释是,我不能保证返回的计数是否是增量之前或之后.然而,这似乎是一些略有不同的解释,那就是发现自己在错误的地方.我的意思是说如果我同步getCount(),那么我仍然看不到保证 – 它现在下来不知道锁定顺序,不知道实际读取是否恰好在实际写入之前/之后.

示例2:

以下示例线程安全,如果您假设通过这里没有显示的诡计,这些方法不会同时被调用?如果每次使用随机方法完成,然后被正确读取,或者锁必须是相同的对象,将以预期的方式计数增量? (btw我完全意识到这个例子是多么可笑,但我对理论比实践更感兴趣)

class Counter{

private final Object lock1 = new Object();

private final Object lock2 = new Object();

private final Object lock3 = new Object();

int count = 0;

public void increment1(){

synchronized(lock1){

count++;

}

}

public void increment2(){

synchronized(lock2){

count++;

}

}

public int getCount(){

synchronized(lock3){

return count;

}

}

}

示例3:

事情之前的关系是简单的java概念,还是JVM中的一个实际的东西?即使我可以保证一个概念性的发生 – 在下一个例子的关系之前,java是否足够聪明,如果它内置的东西呢?我假设不是,但这个例子其实是线程安全的?如果它的线程安全,那么如果getCount()没有锁定呢?

class Counter{

private final Lock lock = new Lock();

int count = 0;

public void increment(){

lock.lock();

count++;

lock.unlock();

}

public int getCount(){

lock.lock();

int count = this.count;

lock.unlock();

return count;

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值