标签:this 对象锁 art main lock 作用 color stat 一个
这里我们先创建ObjLock类,并实现Runnable接口。并创建一个Demo类,具有被synchronized关键字修饰的非静态方法与静态方法。
public class ObjLock implements Runnable { Demo demo; public ObjLock(Demo demo){ this.demo = demo; } public void run() { demo.getI(Thread.currentThread().getName()); } public static void main(String[] args){ Demo demo = new Demo(1); Thread thread = new Thread(new ObjLock(demo),"thread0"); Thread thread1 = new Thread(new ObjLock(demo),"thread1"); Thread thread2 = new Thread(new ObjLock(new Demo(2)),"thread2"); thread.start(); thread1.start(); thread2.start(); } } class Demo{ static int i; Demo(int i){ this.i=i; } public static synchronized void staticGetI(String s){ for (int j=0;j<10000;j++){ System.out.println(i+"---------"+s); } } public synchronized void getI(String s){ for (int j=0;j<10000;j++){ System.out.println(i+"---------"+s); } } }
运行程序,可以看到如下结果:
1---------thread0 1---------thread0 2---------thread2 1---------thread0 2---------thread2 1---------thread0 1---------thread1 1---------thread1 2---------thread2 1---------thread1 1---------thread1 1---------thread1
可以看到Thread0和Thread2交替出现,Thread1和Thread2交替出现,但Thread0和Thread1不会交替出现。
因为对非静态方法加锁,实际上是对调用该方法的对象加锁。Thread0和Thread1用的是同一个对象,所以互斥,但是Thread2则不受影响。
将getI方法改成static之后
public void run() { demo.staticGetI(Thread.currentThread().getName()); }
测试发现三个线程均互斥。
当synchronized修饰一个static方法时,多线程下,获取的是类锁(即Class本身,注意:不是实例),作用范围是整个静态方法,作用的对象是这个类的所有对象。
修改代码
public void run() { if (Thread.currentThread().getName().equals("thread0")){ demo.staticGetI(Thread.currentThread().getName()); }else if (Thread.currentThread().getName().equals("thread1")){ demo.getI(Thread.currentThread().getName()); } }
结果:不会产生互斥。
解释:因为虽然是一个对象调用,但是两个方法的锁类型不同,调用的静态方法实际上是类对象在调用,即这两个方法产生的并不是同一个对象锁,因此不会互斥,会并发执行。
synchronized关键字修饰非静态方法与静态方法的区别
标签:this 对象锁 art main lock 作用 color stat 一个
原文地址:https://www.cnblogs.com/chongaizhen/p/10972747.html