Synchronized常见用法

Synchronized常见的用法

在学习了《Java 核心技术 卷I》之后,对Synchronized有了比较系统的认知
Synchronized的使用方法可以分为修饰代码块和修饰方法两大类,往下细分为5小类:

  • 修饰代码块
    • Synchronized(a1)-括号带参数
    • Synchronized(this)-括号带对象
    • Synchronized(someClass.Class)-括号带类
  • 修饰方法
    • Synchronized-修饰普通方法
    • Synchronized-修饰静态方法

接下来将对以上方法举例说明:

Synchronized修饰代码块

  • 1.Synchronized(a1)-括号带参数
public int method(int a1){
 synchronized(a1) {
  //每一次只能有一个线程进入该代码块
 }
}

Synchronized(a1)修饰代码块的使用过程中,括号带着变量。每一次只有一个线程进入该代码块.只有该线程执行完代码块的所有代码并释放锁时,其他线程才能逐个进入该代码块。此时,线程获得的是成员锁


  • 2.Synchronized(obj)-括号带对象
class Test implements Runnable{
   private Obj obj;        //创建Obj的实例
   public Test(Obj obj) {  
      this.obj = obj;      //对obj进行初始化
   }

   public void run() {
      synchronized (obj) {
         obj.method();     //method是obj中的方法
      }
   }
}

如上代码,当Synchronized(obj)-括号带对象时,若某线程进入,获得对象锁,期间其他试图访问obj对象的线程将会阻塞,直到该线程访问obj对象结束。即某线程获得该对象的对象锁之后,就能对其拥有使用权,而其他的线程这时候只能等待其释放锁。
Ps:我们知道synchronized(obj)锁定的是对象,如果有两个对象,那么就会有两把锁分别锁定相应对象,而这两把锁是互不干扰的,不形成互斥,也就是说两个对象的两个线程可以同时执行。


  • 3.Synchronized(someClass.Class)-括号带类
public static void method() {
      synchronized(Obj.class) {
         //todo
      }
   }

Synchronized作用于一个类Obj时,是给这个类Obj加对象锁。与第二类别:“括号带对象”不同的是,Obj的所有对象用的是同一把锁。也就是说,该类所有的对象中只有一个线程能获得对象锁,拥有其使用权,等其释放锁的时候,其他线程才能相继进入。而上边的第二类别:“括号带对象”的准则是每一个对象只能允许一个线程进入,N个对象可以进入N个进程,互不干扰。这一点要谨记。



Synchronized修饰方法

  • 4.Synchronized-修饰普通方法
方法一:
public synchronized void method()
{
   // todo
}
方法二:
public void method()
{
   synchronized(this) {
      // todo
   }
}

Synchronized-修饰普通方法比较简单,写法二修饰的是一个代码块,写法一与写法二是的效果是一致的,都是锁定了整个方法时的内容。当线程进入该方法时,其他线程都不允许进入。


  • 5.Synchronized-修饰静态方法
 public synchronized static void method() {
      //todo
   }

静态方法、静态变量都是属于类的而不属于对象。触类旁通,synchronized修饰的静态方法锁定的也是这个类的所有对象。即作用的范围是该类的生成的对象。



小结:
1. 如果synchronized作用的是一个静态方法或一个类,则锁定的该类,即该类所有的对象共享同一把锁;
2. 如果它作用的方法是非静态的,则它取得的锁是对象;



发表人:梦想的边缘

`synchronized` 关键字可以用于修饰代码块,以实现对指定对象的同步访问。下面是使用 `synchronized` 锁对象的一些常见用法: 1. 锁定实例对象: ```java public class MyClass { private Object lock = new Object(); public void method() { synchronized (lock) { // 线程安全的代码 } } } ``` 在这个例子中,`lock` 对象被用作锁定对象。当某个线程执行 `method()` 方法时,它必须先获得 `lock` 对象的锁才能进入代码块执行。其他线程需要等待锁释放后才能执行。 2. 锁定类对象: ```java public class MyClass { public static void method() { synchronized (MyClass.class) { // 线程安全的代码 } } } ``` 在这个例子中,`MyClass.class` 被用作锁定对象。由于 `MyClass.class` 是类对象,因此所有实例对象共享同一个锁。只有一个线程可以同时执行被 `synchronized` 修饰的代码块。 3. 锁定字符串对象: ```java public class MyClass { private String lock = "lock"; public void method() { synchronized (lock) { // 线程安全的代码 } } } ``` 在这个例子中,一个字符串对象被用作锁定对象。与上述情况类似,只有一个线程可以同时执行被 `synchronized` 修饰的代码块。 注意事项: - 锁定对象应该是线程共享的,以确保不同线程之间的同步。 - 对于锁定的代码块,尽量使其范围小,避免过长时间持有锁,影响程序性能。 - 对于锁定对象,应当选择合适的对象作为锁,避免出现死锁或竞争条件。 希望以上回答对你有所帮助。如果还有其他问题,请随时提问。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值