在同一个类中如果两个不同的方法method都被synchronized修饰,然后启动两个线程分别访问method1和method2,运行程序会发现只有一个方法被调用,另外一个方法根本没有被调用,原因是synchronized修饰了同一个实例对象的两个不同方法,T1线程获取了monitor的lock并且处于休眠状态,而T2线程企图获取monitor的lock时陷入阻塞状态,可见使用synchronized关键字同步类的不同实例方法,争抢的是同一个monitor的lock,而与之关联的引用则是该类的实例引用,我们来看下具体情况:
public class ThisMon {
public synchronized void method1(){
Log.e("ThisMon","Methond1执行");
try {
TimeUnit.MINUTES.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void method2(){
Log.e("ThisMon","Methond2执行");
try {
TimeUnit.MINUTES.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class ThisMon {
public synchronized void method1(){
Log.e("ThisMon","Methond1执行");
try {
TimeUnit.MINUTES.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void method2(){
synchronized (this) {
Log.e("ThisMon", "Methond2执行");
try {
TimeUnit.MINUTES.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class ThisMon {
public static synchronized void method1(){
Log.e("ThisMon","Methond1执行");
try {
TimeUnit.MINUTES.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static synchronized void method2(){
Log.e("ThisMon", "Methond2执行");
try {
TimeUnit.MINUTES.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class ThisMon {
public static synchronized void method1(){
Log.e("ThisMon","Methond1执行");
try {
TimeUnit.MINUTES.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void method2(){
synchronized (ThisMon.class) {
Log.e("ThisMon", "Methond2执行");
try {
TimeUnit.MINUTES.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class ThisMonMainActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ThisMon mon=new ThisMon();
new Thread(new Runnable() {
@Override
public void run() {
mon.method1();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
mon.method2();
}
}).start();
}
}
12-21 18:29:51.222 2210-2230/e.lenovo.textapplication E/ThisMon: Methond2执行
synchronized有两个明显的缺陷,第一,无法控制阻塞时长,第二,阻塞不可被中断











网友评论