0
点赞
收藏
分享

微信扫一扫

Java多线程.Synchronized

陈情雅雅 2022-04-20 阅读 197

包括内容

同步方法块

同步方法

同步静态方法

示例代码

/**
 * A. 无论synchronized关键字加在方法上还是对象上,如果它作用的对象是非静态的,则它取得的锁是对象;如果synchronized作用的对象是一个静态方法或一个类,则它取得的锁是对类,该类所有的对象同一把锁。
 * B. 每个对象只有一个锁(lock)与之相关联,谁拿到这个锁谁就可以运行它所控制的那段代码。
 * C. 实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制。
 */
public class Synchronized1 {
	
	private class Lock1 {}
	private Lock1 lock = new Lock1();
	
	/**
	 * 同步方法块
	 * 调用:obj.synchronizeFun()
	 * 锁的对象是obj.lock
	 */
	public void synchronizeCode(){
		synchronized(lock){
			//逻辑
		}
		
	}
	/**
	 * 同步方法
	 * 调用:obj.synchronizeFun()
	 * 锁的对象是obj这个对象
	 * 说明:synchronizeFun1 和 synchronizeFun2 功能类似
	 */
	public synchronized void synchronizeFun1(){
		//逻辑
	}
	public void synchronizeFun2(){
		synchronized(this){
			//逻辑
		}
	}
	/**
	 * 同步静态方法
	 * 调用:Synchronize1.synchronizeStaticFun
	 * 锁的是所有对象
	 */
	public static synchronized void synchronizeStaticFun(){
		
	}
}

总结:搞清楚锁的对象是什么

A. 无论synchronized关键字加在方法上还是对象上,如果它作用的对象是非静态的,则它取得的锁是对象;如果synchronized作用的对象是一个静态方法或一个类,则它取得的锁是对类,该类所有的对象同一把锁。

B. 每个对象只有一个锁(lock)与之相关联,谁拿到这个锁谁就可以运行它所控制的那段代码。

C. 实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制

嵌套synchronized

嵌套可能导致死锁。

/**
 * 测试死锁
 * 1. synchronized(lock) 只锁了lock一个对象
 * 2. 可以在synchronized方法块中继续同步
 * synchronized (lock1) {
 * 		synchronized (lock2) {}
 * }
 * 3.如示例:
 * 	- 线程和main 分别锁了 t1,t2
 * 	- 1s后 线程需要 t2, main 需要 t1, 彼此并没有把获取的对象释放,就要彼此的资源,导致了死锁
 * 4.死锁原因:
 * 	一次没能获取完所需要同步的资源,再次获取是,发现资源被人占用,且占用资源的人,还需要你以及上锁的东西。
 * 5. 无法使用interrupt对synchronized对资源的等待,也没法打断ReentrantLock.lock的等待
 * 	- 可以使用interrupt对ReentrantLock.lockInterruptibly对资源的等待,见TestThreadLock3
 */
public class TestThreadLock2 implements Runnable{
	
	private static Logger log = Logger.getLogger(TestThreadLock2.class);
	
	private Object t1 = null;
	private Object t2 = null;
	
	public TestThreadLock2(Object t1,Object t2){
		this.t2 = t2;
		this.t1 = t1;
	}

	public static void main(String[] args) throws Exception {
		Object t1 = new Object();
		Object t2 = new Object();
		
		Thread th1 = new Thread(new TestThreadLock2(t1,t2));
		Thread th2 = new Thread(new TestThreadLock2(t2,t1));
		
		th1.start();
		th2.start();
		
		char c = (char) System.in.read();
		log.info("input : " + c);
		if(c == 'y'){
			th1.interrupt();
		}
	}

	public void run() {
		try {
			synchronized (t1) {
				log.info("get t1 monitor ...");
				Thread.sleep(1000l * 1);
				synchronized (t2) {
					Thread.sleep(1000l * 3);
				}
			}
			log.info("release t1 monitor ...");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

举报

相关推荐

0 条评论