在我最近的采访中,通过解释一个情况,他们询问这个过程是否是线程安全的
有两个同步方法,一个是静态的,另一个不是静态的,即非静态方法A和静态方法B.这两个方法访问共享数据。
现在线程A调用非静态方法A而线程B调用静态方法B.这个线程是否安全并解释y?
答案 0 :(得分:5)
不,它不是线程安全的。为了使其成为线程安全的,不同的线程必须使用相同的锁来访问共享数据,但这两种方法使用不同的锁。将synchronized置于静态方法上将该类用作锁,将synchronized置于实例方法上将该对象用作锁。
如果线程使用不同的锁,则两个线程都不会被阻塞,并且两者都可以同时访问或修改数据。即使线程只访问数据,也没有修改它,锁定将确保内存可见性。没有共享锁,您就无法依赖该可见性。只有当数据不可变并且已经safely published时,不受限制的并发访问才是安全的。
假设共享数据必须是可变的,那么修复将是两种方法都使用相同的锁。如果使用synchronized块(而不是同步添加到方法),则始终可以指定自己的锁,因此实例方法可以使用:
public void yourInstanceMethod() {
synchronized(WhateverYourClassIs.class) {
// code accessing shared data
}
}