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

问:谈一谈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。

你可能感兴趣的:(J2EE,面试准备)