正如你所说的counter++
操作是非原子的,所以一次给多个线程访问会导致未定义的行为。在线程安全中,问题几乎总是对共享资源(如静态变量)进行同步访问。
线程在声明方法时获取的锁属于该类。假设我们有一个类
public synchronized void foo() {...}
public synchronized void bar() {...}
两种方法如果一个线程进入foo()
获取到了类的锁,任何其他线程试图访问foo()
ORbar()
将阻塞,直到第一个线程完成。为了克服这个问题,我们可以锁定方法中的独立对象。
// Declare 2 objects to use as locks within the class
private Object fooLock = new Object();
private Objecy barLock = new Object();
// lock on these objects within the method bodies
public void foo {
synchronized(fooLock) { /* do foo stuff */ }
}
public void bar() {
synchronized(barLock) {/* do bar stuff */}
}
现在2个线程可以在foo()
和bar()
同时访问。
网上有很多关于线程安全的资料,如果你想更多地了解有关锁/执行器服务和东西的多线程,我会推荐this一组教程。
“在该函数中获取或修改的任何内容都将是线程安全的。” - 只要一个线程在任何给定的时间在上面的例子中都可以输入getCount()(如果它是在类对象上同步的),但这不会使count变量线程安全。如果其他一些方法也直接访问count变量呢?如果触及它的_every_方法锁定_same lock_,该变量只能是线程安全的。 –