如何在Java中同步对类字段的访问?
类中有一个变量,该变量由多个线程积极使用。例如:如何在Java中同步对类字段的访问?,java,multithreading,Java,Multithreading,类中有一个变量,该变量由多个线程积极使用。例如: public class A { private int magicVar; private void someMethod() { // some operations with magicVar } public synchronized void somePublicMethod() { // some operations with magicVar }
public class A {
private int magicVar;
private void someMethod() {
// some operations with magicVar
}
public synchronized void somePublicMethod() {
// some operations with magicVar
}
private class B extends Thread {
@Override
private void run() {
// some operations with magicVar
}
}
}
在这种情况下,如何组织对变量的访问?描述私有同步setter和getter?或者将此字段标记为违反?使该字段变为易变字段将确保线程之间的可见性,但如果您正在执行以下操作:
a = a + 2;
这是一个复合操作,不是原子操作。要使字段的最新更改对所有线程可见并执行原子操作,可以将someMethod()和somePublicMetod()标记为已同步
或者创建具有锁定对象的更精细的同步块
Object lock = new Object(); // make this an instance variable
// ...
// then each time you need to make operations with your contended field you can do
synchronized(lock) {
// make changes to your contended field
}
这完全取决于你计划如何使用你的课程。同步不是一个实现细节,它是设计的一部分
在保护对整数的访问时,考虑使用
AtomicInteger
。对于int a;a=a+2;`你也可以把a
变成一个AtomicInteger
,它可以适当地处理增量。否决一个同事的答案不是很好,但重要的是:在使用synchronized
之前,你绝对应该使用AtomicInteger
,而且您绝对不应该建议将synchronized
作为一种通用的线程安全模式。这很少是正确的做法,自由使用会导致严重的死锁。@user3149106显然不了解多线程编程的基础知识,因此我建议使用synchronized,这对新手来说更安全,所有涉及共享资源的访问都可以正常工作。如果你遇到了死锁,那么你的代码就足够复杂了——一个简单的问题,所以对你的基础知识没有帮助。如果您使用AtomicInteger,您仍然可以在复合操作中使用它,这仍然会导致“同步”问题。作为旁注。我还推荐了《Java并发实践》一书。同步是一个很难的话题。如果您在实践中阅读Java并发,您将有一个更好的开始。