Java基础 之 synchronized使用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_34083066/article/details/86798598

synchronized关键字

给对象加锁。当请求进入该方法时或者代码块时,先检查是否有其他线程占用,如果有则等待其执行完释放锁才能获得锁。

修饰对象不同,效果也不同。

当修饰的是普通方法或者普通代码块时,只有是使用同一实例时,才能有锁的效果。当是不同实例的时候,锁无效。

当修饰的是静态方法或者静态代码块时,无论使用的实例是否相同,都会有加锁的效果。因为类初始化时,静态方法和静态代码块都会初始化到类的内存中,所以每个实例使用的都是一个静态方法或者静态代码块。

synchronized类型

对象锁

使用synchronized关键字给普通方法,普通代码块进行加锁。

例如:

import lombok.extern.slf4j.Slf4j;

/**
 * 对象锁
 * 使用synchronized对象锁进行并发控制
 * @author wm
 *
 */
@Slf4j
public class SyncDemo2 implements Runnable{

	static SyncDemo2 instance = new SyncDemo2();
	
	Object lock1 = new Object();
	Object lock2 = new Object();
	
	public static void main(String[] args) throws InterruptedException {
		log.info("start");
		Thread t1 = new Thread(instance);
		Thread t2 = new Thread(instance);
		t1.start();
		t2.start();
		t1.join();
		t2.join();
		log.info("finish");
	}
	
	/**
	 * 普通方法锁
	 */
	@Override
	public synchronized void run() {
		log.info("运行对象锁普通方法锁形式");
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		log.info("运行结束。");	
	}
	
	
	/**
	 * 运行对象锁代码块形式时使用多把锁
	 * 观察进入顺序。
	 * 2019-01-08 14:40:57,887 [INFO] main (SyncDemo2.java:20)- start
	 * 2019-01-08 14:40:57,891 [INFO] Thread-0 (SyncDemo2.java:36)- 运行对象锁代码块形式,lock1
	 * 2019-01-08 14:41:00,893 [INFO] Thread-0 (SyncDemo2.java:42)- lock1运行结束。
	 * 2019-01-08 14:41:00,894 [INFO] Thread-0 (SyncDemo2.java:45)- 运行对象锁代码块形式,lock2
	 * 2019-01-08 14:41:00,895 [INFO] Thread-1 (SyncDemo2.java:36)- 运行对象锁代码块形式,lock1
	 * 2019-01-08 14:41:03,895 [INFO] Thread-0 (SyncDemo2.java:51)- lock2运行结束。
	 * 2019-01-08 14:41:03,896 [INFO] Thread-1 (SyncDemo2.java:42)- lock1运行结束。
	 * 2019-01-08 14:41:03,897 [INFO] Thread-1 (SyncDemo2.java:45)- 运行对象锁代码块形式,lock2
	 * 2019-01-08 14:41:06,898 [INFO] Thread-1 (SyncDemo2.java:51)- lock2运行结束。
	 * 2019-01-08 14:41:06,899 [INFO] main (SyncDemo2.java:27)- finish
	 */
//	@Override
//	public void run() {
//		synchronized (lock1) {
//			log.info("运行对象锁代码块形式,lock1");
//			try {
//				Thread.sleep(3000);
//			} catch (InterruptedException e) {
//				e.printStackTrace();
//			}
//			log.info("lock1运行结束。");	
//		}
//		synchronized (lock2) {
//			log.info("运行对象锁代码块形式,lock2");
//			try {
//				Thread.sleep(3000);
//			} catch (InterruptedException e) {
//				e.printStackTrace();
//			}
//			log.info("lock2运行结束。");	
//		}
//	}

	/**
	 * 运行对象锁代码块形式
	 */
//	@Override
//	public void run() {
//		synchronized (this) {
//			log.info("运行对象锁代码块形式");
//			try {
//				Thread.sleep(3000);
//			} catch (InterruptedException e) {
//				e.printStackTrace();
//			}
//			log.info("运行结束。");	
//		}
//	}
	
	/**
	 * 没进行任何锁保护
	 * 执行时,会同时进行,同时结束。
	 */
//	@Override
//	public void run() {
//		log.info("对象锁代码块形式");
//		try {
//			Thread.sleep(3000);
//		} catch (InterruptedException e) {
//			e.printStackTrace();
//		}
//		log.info("运行结束。");
//	}

}

类锁

给静态方法或者静态代码块进行加锁。

例如:

扫描二维码关注公众号,回复: 5426848 查看本文章
import lombok.extern.slf4j.Slf4j;

/**
 * 类锁
 * 使用synchronized类锁进行并发控制
 * 注意区分main中和对象锁的不同
 * 两个想成使用的是两个不同的实例,如果是对象锁,就无法达到控制并发的效果了
 * 但是如果使用类锁还可以达到这样的效果
 * @author wm
 *
 */
@Slf4j
public class SyncDemo3 implements Runnable{

	static SyncDemo3 instance1 = new SyncDemo3();
	static SyncDemo3 instance2 = new SyncDemo3();
	
	Object lock1 = new Object();
	Object lock2 = new Object();
	
	public static void main(String[] args) throws InterruptedException {
		log.info("start");
		Thread t1 = new Thread(instance1);
		Thread t2 = new Thread(instance2);
		t1.start();
		t2.start();
		t1.join();
		t2.join();
		log.info("finish");
	}
	
	@Override
	public void run() {
		method();	
	}

	/**
	 * 类锁的静态方法形式
	 */
	private static synchronized void method() {
		log.info("运行类锁形态方法形式");
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		log.info("运行结束。");
	}
	

	/**
	 * 运行类锁代码块形式
	 */
//	@Override
//	public void run() {
//		synchronized (SyncDemo3.class) {
//			log.info("运行类锁代码块形式");
//			try {
//				Thread.sleep(3000);
//			} catch (InterruptedException e) {
//				e.printStackTrace();
//			}
//			log.info("运行结束。");	
//		}
//	}
	

}

猜你喜欢

转载自blog.csdn.net/qq_34083066/article/details/86798598