【面试题】sychronized中类锁和对象锁的区别

博客主要探讨了synchronized中类锁和对象锁的区别。对静态方法或使用synchronized(XX.class)加的是类锁,对实例方法或用synchronized(this或对象)加的是对象锁。同一类不同实例,类锁需等待释放,对象锁可并发执行,且一个线程能同时获取两把锁。

问:谈一谈sychronized中类锁和对象锁的区别。

答:类锁和对象锁是两种不同的锁,对静态方法加锁或者使用sychronized(XX.class)相当于加了类锁,对实例方法加锁或者采用sychronized(this或对象)相当于加了对象锁,区别在于对于同一个类的不同实例来说,如果加了类锁,那么在一个线程获得类锁后,其他线程即使是持有同一个类的不同的实例,也得等待类锁的释放,因为它们竞争的都是类锁,如果一个线程获得了对象锁,那么持有不同对象的线程则可以并发执行,因为虽然竞争的都是对象锁,但并不是同意把对象锁。既然类锁和对象锁是不同的锁,那么一个线程可以同时获取两把锁。

class MyThread1 extends Thread {

	private TestSychronized test;

	public MyThread1(TestSychronized test) {
		this.test = test;
	}

	@Override
	public void run() {
		test.fun1();
		test.fun3();
	}

}

class MyThread2 extends Thread {

	private TestSychronized test;

	public MyThread2(TestSychronized test) {
		this.test = test;
	}

	@Override
	public void run() {
		test.fun2();
		test.fun4();
	}
}

public class TestSychronized {

	static synchronized void fun1() {
		System.out.println(Thread.currentThread().getName() + "静态方法锁fun1,等待2s");
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	static synchronized void fun2() {
		System.out.println(Thread.currentThread().getName() + "静态方法锁fun2,等待2s");
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	synchronized void fun3() {
		System.out.println(Thread.currentThread().getName() + "实例方法锁fun3,等待2s");
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	synchronized void fun4() {
		System.out.println(Thread.currentThread().getName() + "实例方法锁fun4,等待2s");
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {

		TestSychronized ts1 = new TestSychronized();
		TestSychronized ts2 = new TestSychronized();
		MyThread1 mt1 = new MyThread1(ts1);
		MyThread1 mt2 = new MyThread1(ts2);
//		MyThread2 mt3 = new MyThread2(ts1);
//		MyThread2 mt4 = new MyThread2(ts2);

		mt1.start();
		mt2.start();
//		mt3.start();
//		mt4.start();

		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

}

上面代码执行顺序的一种情况是:

Thread-0和Thread-1要竞争类锁,Thread-1拿到了,先执行,然后等待2s,执行完成释放类锁,Thread-0可以获得类锁,同时Thread-1可以获取对象锁,这两个锁不冲突,锁Thread-0:fun1和Thread-1:fun3可以并发执行,Thread-0执行完fun1后,等待2s,然后执行fun3。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值