synchronized修饰static方法,非static方法,代码块的区别(类锁,对象锁)一个类中多个synchronized

本文详细解析了synchronized关键字在Java中的四种使用方式及其作用范围和对象,包括代码块、非静态方法、静态方法及类级别,并对比了其与ReentrantLock的性能与使用场景。

今天看了很多关于synchronized的博客,全部都是模棱两可很多都是抄的,上下不接的,很烦啊,去看看视频和实验一下,做个简单的记录,面试备用.


重点看一下: synchronized是同步锁,他所有修饰都是同步的.
作用的范围:synchronized所影响的一个或多个方法
作用的对象:synchronized所影响的一个或多个类


第一种 修饰一个代码块
synchronized(obj)
{
    //逻辑
}

这是同步代码块

  1. 作用的范围:是大括号{}括起来的代码
  2. 作用的对象:是调用这个代码块的对象
第二种 修饰一个非静态方法
public  synchronized void test1()
{
    //逻辑
}

底层synchronized 作用在对象上

  1. 作用的范围:整个方法
  2. 作用的对象:调用这个方法的对象
  3. 解释:也就是说调用这个方法的对象,如果里面有很多被synchronized 修饰方法情况下,
    有一个被调用其他的都得等着(但是不包含synchronized 静态方法).
第三种 修饰一个静态方法
public  static  synchronized void test1()
{
    //逻辑
}

底层synchronized 作用在类上

  1. 作用的范围:整个静态方法
  2. 作用的对象:这个类的所有对象
  3. 解释:此类所有对象(被new出了好几个对象)有多个被synchronized 修饰静态方法情况下,
    只要是有一个对象中一个静态方法被占用,其他所有对象中所有静态方法都得等着(但是不包含synchronized 普通方法).
第四种 修饰一个类
  1. 作用的范围:synchronized后面括号括起来的部分
  2. 作用的对象:这个类的所有对象
  3. 解释:没啥说的,就是一个类都锁了,不管什么方法,不管几个对象,一个吊用,其他都锁.

补充:修饰非静与修饰静,

  1. 修饰非静:这个就是对象锁(一个对象中有两个方法同时被synchronized,调用这两个方法时,只能同时执行一个。但它并不能使调用该方法的多个对象在执行顺序上互斥,就是多个对象调用这个方法它就没办法保证数据是不是出现同时被使用脏读这些问题,不知道描述精准吗,请大佬指正)

  2. 修饰静:这个就是类锁了,一锁锁一个类的所有对象.

  3. 修饰非静与修饰静,出现在同一个对象中他们不是一个锁, 各走各的,相互不影响.

以上是面试时候用的,如果我自己写线程锁肯定用ReentrantLock,毕竟synchronized的性能不提jdk的版本都是耍流氓,synchronized在1.6之前和1.8之后就是两个级别的,而且synchronized是重量锁底层是本地方法调用cpu,ReentrantLock却是一个在虚拟机里运用行的一组算法.(这几天整理一下写写ReentrantLock底层算法)

### Java 中 `synchronized` 静态方法定的对象 在 Java 中,当 `synchronized` 关键字被应用于静态方法时,它实际上是对 **对象** 进行定。这是因为静态方法属于本身而不是某个特定的实例[^4]。换句话说,所有的静态成员都归属于 Class 对象,而这个 Class 对象在整个应用程序运行期间是唯一的。 对于静态同步方法而言,其机制依赖于当前对应的 Class 对象。这意味着如果多个线程试图同时执行同一个中的任意静态同步方法,则它们会被强制按顺序依次执行,因为这些方法共享同一把——即该的 Class 对象锁[^5]。 以下是通过代码展示这一特性的例子: ```java public class Counter { private static int count = 0; // 使用 synchronized 修饰静态方法 public synchronized static void increment() { try { Thread.sleep(100); // 模拟耗时操作 } catch (InterruptedException e) { e.printStackTrace(); } count++; System.out.println(Thread.currentThread().getName() + " increments count to: " + count); } public static void main(String[] args) { Runnable task = () -> Counter.increment(); // 创建并启动多条线程访问静态同步方法 new Thread(task, "Thread-A").start(); new Thread(task, "Thread-B").start(); new Thread(task, "Thread-C").start(); } } ``` 在这个程序里,三个独立线程分别尝试调用 `Counter` 里的 `increment()` 方法。然而由于此方法声明为 `static` 并加上了 `synchronized` 修改符,所以每次仅允许一条线程真正进入临界区修改变量 `count` 的值,并打印相应的消息到标准输出流中[^3]。 值得注意的是,尽管上述讨论集中在静态上下文中应用 `synchronized` 上面,但在静态场景下(也就是普通实例方法),所使用的则是对应实例自身的监视器作为资源[^1]^。 综上所述,当我们在定义一个带有 `synchronized` 和 `static` 双重属性的方法时,实际上是基于所属型的元数据结构(Class Object)实施互斥控制策略;而对于普通的静态版本来说,则是以具体的实体(instance object)为基础构建这种约束关系。 ####
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值