synchronized(this)和synchronized(.class)的理解
- synchronized(this)
- 验证:
- 同一对象的Thread(苇名一心):
- 不同对象的Thread(苇名一心和苇名弦一郎)
- synchronized( .class)
- 验证:
对象锁(this)和类锁(class)产生的效果不同,对象锁只对当前对象加锁,而类锁是对指定类加锁。
举个例子:
class person implements Runnable,其中run方法是循环释放巴之雷。假设在释放巴之雷上加锁.
person 苇名一心 = new person();
person 苇名弦一郎 = new person();
实例化出苇名一心和苇名弦一郎两个对象来创建Thread
如果用synchronized(苇名一心),表示对苇名一心这个对象加了锁,这时,苇名一心只能等一个巴之雷放完再放另一个巴之雷(同步),不能同时放好几个巴之雷。但锁的是苇名一心,苇名弦一郎就不会被这个对象锁制约,他就可以和苇名一心同时放巴之雷。
如果用synchronized(person),表示对person这个类加了锁,而苇名一心和苇名弦一郎都是person这个类的对象,那么两人只要有一个在放巴之雷,person类中放巴之雷这个过程就会被锁住,只有等一个巴之雷放完,下一个巴之雷才能继续放。
synchronized(this)
synchronized(this)锁的是当前对象,this代表了对象锁,此时被synchronized锁住的代码块只在当前对象同步,如果有其他对象就不会同步了。
验证:
用Person类来实现Runnable接口。让它来实现释放100次巴之雷。
//测试this
class Person implements Runnable
{public void run() {synchronized (this) {for(int i = 0; i <= 100; i++){try {Thread.sleep(200);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println(Thread.currentThread().getName()+"放巴之雷");} }}
}
同一对象的Thread(苇名一心):
public class Test1 {public static void main(String[] args) {Person you = new Person();//同一对象new出来的thread,受this锁会同步Thread you1 = new Thread(you, "苇名一心1");Thread you2 = new Thread(you,"苇名一心2"); you1.start();you2.start();}
}
输出结果:苇名一心1和苇名一心2不能同时放100次巴之雷,只有一个放完第二个才能放。
查看输出结果可以看到同一对象创建出来的Thread是一个线程被锁住的代码块执行完后,才执行另一个线程被锁住的代码块,实现了同步。
不同对象的Thread(苇名一心和苇名弦一郎)
由于this锁是锁住的当前对象,对于用不同对象new出来的Thread,不会受this锁的影响,也就不会实现同步。
public class Test1 {public static void main(String[] args) {Person you = new Person();Person he = new Person();不同对象new出来的thread,不会同步Thread you1 = new Thread(you, "苇名一心");Thread he1 = new Thread(he,"苇名弦一郎");you1.start();he1.start();}}
结果:
可以看到you1和he1两个线程同时执行,并没有被同步。
synchronized( .class)
.class是一个类锁,对整个类进行加锁。在this的基础上还可以对同一类的不同对象进行同步。
//测试this
class Person implements Runnable
{public void run() {synchronized (Person.class) {for(int i = 0; i <= 100; i++){try {Thread.sleep(200);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println(Thread.currentThread().getName()+"放巴之雷");} }}
}
验证:
public class Test1 {public static void main(String[] args) {Person you = new Person();Person he = new Person();//不同对象,在类锁下会同步。Thread you1 = new Thread(you, "苇名一心");Thread he1 = new Thread(he,"苇名弦一郎");you1.start();he1.start();}}
多次测试后发现可以实现同步。