synchronized(this)和synchronized(.class)的理解

  • Post author:
  • Post category:其他


对象锁(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 block
					e.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 block
					e.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();
	}
	
}

多次测试后发现可以实现同步。



版权声明:本文为weixin_44127579原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。