如何在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并发,您将有一个更好的开始。