Synchronized关键字

1.Synchronized关键字的作用:能够保证在同一时刻最多只有一个线程执行该段代码,以达到保证并发安全的效果。
2.Synchronized的两个用法:
对象锁:包括方法锁(默认锁对象为this当前实例对象)和同步代码块锁(自己指定锁对象)
方法锁举例:

public class SynchronizedObjectMethod implements Runnable {
	static SynchronizedObjectMethod instance = new SynchronizedObjectMethod();

	@Override
	public void run() {
		method();
	}

	public synchronized void method() {
		System.out.println("我是对象锁的方法修饰符形式,我叫" + Thread.currentThread().getName());
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(Thread.currentThread().getName() + "运行结束");
	}

	public static void main(String[] args) {
		Thread t1 = new Thread(instance);
		Thread t2 = new Thread(instance);
		t1.start();
		t2.start();
		while (t1.isAlive() || t2.isAlive()) {

		}
		System.out.println("finished");
	}
}

在这里插入图片描述
同步代码块形式:

public class SynchronizedObjectCodeBlock implements Runnable {
	static SynchronizedObjectCodeBlock instance = new SynchronizedObjectCodeBlock();
	Object lock = new Object();

	@Override
	public void run() {
		synchronized (lock) {  //默认为this为当前的实例化对象 
			System.out.println("我是对象锁的代码块形式,我叫" + Thread.currentThread().getName());
			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

			System.out.println(Thread.currentThread().getName() + "运行结束");
		}

	}

	public static void main(String[] args) {
		Thread t1 = new Thread(instance);
		Thread t2 = new Thread(instance);
		t1.start();
		t2.start();
		while (t1.isAlive() || t2.isAlive()) {

		}
		System.out.println("finished");
	}
}

在这里插入图片描述
类锁:指synchronized修饰静态的方法或指定锁为Class对象
概念:java类可能有很多个对象,但只有1个Class对象,所谓的类锁,本质上是Class对象的锁。类锁只能在同一时刻被一个对象拥有。
形式1:synchronized加在static方法上

public class SynchronizedClassStatic implements Runnable {

	static SynchronizedClassStatic instance1 = new SynchronizedClassStatic();
	static SynchronizedClassStatic instance2 = new SynchronizedClassStatic();

	@Override
	public void run() {
		method();

	}

	public static synchronized void method() {
		System.out.println("我是类锁的第一种形式:static形式,我叫" + Thread.currentThread().getName());
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(Thread.currentThread().getName() + "运行结束");
	}

	public static void main(String[] args) {
		Thread t1 = new Thread(instance1);
		Thread t2 = new Thread(instance2);
		t1.start();
		t2.start();
		while (t1.isAlive() || t2.isAlive()) {

		}
		System.out.println("finished");
	}
}

在这里插入图片描述

形式2:synchronized(*.class)代码块

public class SynchronizedClassClass implements Runnable {

	static SynchronizedClassClass instance1 = new SynchronizedClassClass();
	static SynchronizedClassClass instance2 = new SynchronizedClassClass();

	@Override
	public void run() {
		method();

	}

	public void method() {
		synchronized (SynchronizedClassClass.class) {
			System.out.println("我是类锁的第二种形式:synchronized(*.class)形式,我叫" + Thread.currentThread().getName());
			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName() + "运行结束");
		}
	}

	public static void main(String[] args) {
		Thread t1 = new Thread(instance1);
		Thread t2 = new Thread(instance2);
		t1.start();
		t2.start();
		while (t1.isAlive() || t2.isAlive()) {

		}
		System.out.println("finished");
	}
}

在这里插入图片描述
3.多线程访问同步方法的7种情况:
(1)两个线程同时访问一个对象(实例)的同步方法:使用的是同一把锁,会产生同步效果。
(2)两个线程访问的是两个对象(实例)的同步方法:synchronized不起作用,因为采用的所对象不是同一个。
(3)两个线程访问的是synchronized的静态方法:锁生效,因为方法是静态的,所以它们对应的锁对象是同一把。
(4)同时访问同步方法和非同步方法:非同步方法不受到影响,同时运行。
(5)访问同一个对象的不同的普通同步方法:产生同步,锁对象都是this,同一把锁
(6)同时访问静态synchronized和非静态synchronized方法:同时运行,因为指定的锁对象不是同一把锁
(7)方法抛异常后,会释放锁

  • 一把锁只能同时被一个线程获取,没有拿到锁的线程必须等待(对应情况1,5)
  • 每个实例都对应有自己的一把锁,不同实例之间互不影响;例外:锁对象是*.class以及synchronized修饰的是static方法的时候,所有对象共用同一把锁(对应情况2,3,4,6)
  • 无论是方法正常执行完毕或者方法抛出异常,都会释放锁(对应情况7)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
synchronized关键字是Java中用于实现线程同步的关键字。它可以用来修饰方法或代码块,以确保在多线程环境下的安全性。 synchronized关键字的使用有以下几点需要注意: 1. synchronized是一种重量级的操作,会影响性能。因此,在使用synchronized时应尽可能减小同步块的范围,避免锁的竞争。 2. synchronized锁的范围应尽量小,只保护必要的代码块,避免对整个方法或对象进行锁定。这样可以提高程序的并发性能。 3. synchronized锁定的对象不应该被修改,否则可能会导致死锁的发生。因此,在使用synchronized时需要谨慎处理锁定的对象。 4. 在使用synchronized时,需要考虑线程间的协调和通信,以避免死锁和活锁的发生。这可以通过合理设计程序逻辑和使用其他同步机制来实现。 总的来说,synchronized关键字是一种常用的线程同步机制,可以确保在多线程环境下的数据安全性和一致性。但是在使用时需要注意性能问题和锁的范围,以及避免死锁和活锁的发生。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [Synchronized 关键字详解](https://blog.csdn.net/swadian2008/article/details/99328700)[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_2"}}] [.reference_item style="max-width: 50%"] - *2* [举例讲解Java中synchronized关键字的用法](https://download.csdn.net/download/weixin_38724611/12798175)[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_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值