Synchronized的使用

Synchronized的使用

1.为什么使用Synchronized

因为在并发编程中,多线程并发操作共享数据会出现数据安全问题。使用
Synchronized 可以保证同一时刻,只有一个线程能够访问同一个对象的方法。

2.Synchronized的应用方式

1)给普通方法加锁,是锁住的当前对象
2)给代码块加锁,锁住的是给定的对象
3)给静态方法加锁,锁的是当前类型的类对象,简称类锁

3.代码示例

应用1)和2)的代码

public class Test_01 {
	private int count = 0;
	private Object o = new Object();
	
	public void testSync1(){
		synchronized(o){
			System.out.println(Thread.currentThread().getName() 
					+ " count = " + count++);
		}
	}
	
	public  void testSync2(){
		synchronized(this){
			System.out.println(Thread.currentThread().getName()
					+ " count = " + count++);
			try {
				TimeUnit.SECONDS.sleep(3);
				System.out.println("3s后"+Thread.currentThread().getName());
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
	public synchronized void testSync3(){
		System.out.println(Thread.currentThread().getName() 
				+ " count = " + count++);
		try {
			TimeUnit.SECONDS.sleep(3);
			System.out.println("3s后"+Thread.currentThread().getName());
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		final Test_01 t = new Test_01();
		new Thread(new Runnable() {
			@Override
			public void run() {
				t.testSync2();
			}
		}).start();
		new Thread(new Runnable() {
			@Override
			public void run() {
				t.testSync3();
			}
		}).start();
	}
	
}

在这里插入图片描述
结果分析:
synchronized(this)和synchronized方法都是锁当前对象。
1.当两个并发线程访问同一个对象object中的这个synchronized(this)同步方法时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个方法以后才能执行该方法,但是可以访问非同步方法。保证了方法访问的互斥和变量可见性
2.不同对象锁不相互影响。对于上述testSync1,锁住的是对象o。testSync1和testSync2是不同对象的同步方法,可以同时执行。
3.两个线程访问同一对象的不同synchronized方法,互斥。

应用3)的代码

private static int staticCount = 0;
	public static synchronized void testSync4(){
		System.out.println(Thread.currentThread().getName() 
				+ " staticCount = " + staticCount++);
		try {
			TimeUnit.SECONDS.sleep(3);
			System.out.println("3s后"+Thread.currentThread().getName());

		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public static void testSync5(){
		synchronized(Test_02.class){
			System.out.println(Thread.currentThread().getName() 
					+ " staticCount = " + staticCount++);
		}
	}
	public static void main(String[] args) {
		final Test_02 t = new Test_02();
		new Thread(new Runnable() {
			@Override
			public void run() {
				t.testSync4();
			}
		}).start();
		new Thread(new Runnable() {
			@Override
			public void run() {
				t.testSync5();
			}
		}).start();
	}

分析结果:
在这里插入图片描述
两个线程实例化两个不同的对象,但是访问的方法是静态的,两个线程发生了互斥。同步静态方法是类对象锁。testSync5锁的也是类对象。
其他情况,比如两个线程访问同步静态方法和非同步方法,是不互斥的。

4.可重入锁

可重复可递归调用的锁。同一个线程,递归调用同步代码,锁定的是同一个锁对象,可重入。
代码举例:

	synchronized void m1(){ // 锁this
		System.out.println("m1 start");
		try {
			TimeUnit.SECONDS.sleep(2);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		m2();
		System.out.println("m1 end");
	}
	synchronized void m2(){ // 锁this
		System.out.println("m2 start");
		try {
			TimeUnit.SECONDS.sleep(1);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("m2 end");
	}
	
	public static void main(String[] args) {
		new Thread(new Runnable() {
			@Override
			public void run() {
				new Test_06().m1();
			}
		}).start();
	}

执行结果:
m1 start
m2 start
m2 end
m1 end

m1()中正常调用m2(),可重入。

synchronized 是一种悲观锁,每次执行临界区代码都会产生冲突,当前线程获得锁后,其他线程只能阻塞。

在Java中,synchronized关键字用于实现线程之间的同步。它可以应用于方法或代码块上。在方法上使用synchronized关键字,可以确保同一时间只有一个线程可以访问该方法。而在代码块上使用synchronized关键字,可以确保同一时间只有一个线程可以访问被同步的代码块。 在引用中,演示了在同步代码块中使用synchronized关键字的情况。在SynchronizedDemo类的method方法中,使用synchronized关键字来同步代码块,以保证线程安全。 引用展示了子类继承父类,并重写了同步方法的情况。在SynchronizedUsageChild类的synchronizedMethod1方法中,通过使用synchronized关键字来同步方法,确保在多线程环境下,同一时间只有一个线程可以访问该方法。在该方法中,还演示了可重入锁的概念,即子类在同步方法中调用父类的同步方法。 总结来说,synchronized关键字用于实现线程之间的同步,可以应用于方法或代码块上,以确保多线程环境下的线程安全性。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Synchronized 详解](https://blog.csdn.net/qq_43322057/article/details/104258758)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [Java synchronized使用案例](https://download.csdn.net/download/visionliao/8368107)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [synchronized用法详解](https://blog.csdn.net/ganmaotong/article/details/124501478)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值