【学习笔记】Java中同步Sychronized关键字

本文详细介绍了Java中synchronized关键字的用法,包括修饰代码块、方法和静态方法,以及其作用原理和效果。通过一个线程同步的例子展示了synchronized如何确保线程安全,强调了其在多线程环境中的重要性。同时,讨论了synchronized的限制,如不能修饰接口方法和构造函数,以及在修饰静态方法时的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考自文章Java中Synchronized的用法

synchronized是Java中的关键字,是一种同步锁,可以保证其修饰的代码在同一时间只有一个线程能够访问。

0. 快速入门案例

实现了Runnable接口的SyncThread类:

class SyncThread implements Runnable {
   private static int count;

   public SyncThread() {
      count = 0;
   }

   public  void run() {
      synchronized(this) {
         for (int i = 0; i < 5; i++) {
            try {
               System.out.println(Thread.currentThread().getName() + ": " + (count++));
               Thread.sleep(100);
            } catch (InterruptedException e) {
               e.printStackTrace();
            }
         }
      }
   }
}

调用SyncThread类:

SyncThread syncThread = new SyncThread();
Thread thread1 = new Thread(syncThread, "SyncThread1");
Thread thread2 = new Thread(syncThread, "SyncThread2");
thread1.start();
thread2.start();

其输出结果如下:

SyncThread1: 0
SyncThread1: 1
SyncThread1: 2
SyncThread1: 3
SyncThread1: 4
SyncThread2: 5
SyncThread2: 6
SyncThread2: 7
SyncThread2: 8
SyncThread2: 9

可用发现当线程1访问同步代码块时,线程2被阻塞了,只有等到线程1运行完之后线程2才得以执行。

1. 修饰一个代码块

语法:

class ClassName {
    public void method() {
     synchronized(this) {
            // 代码
        }    
    }
}

当一个线程访问对象中的synchronized(this)修饰的代码块时,其他线程对这块代码块的访问将会被阻塞。其中的this表示作用的范围是当前对象。所以如果有多个线程使用了不同的对象来对代码块进行访问时不会有阻塞的情况,只有为同一个对象时才会产生阻塞。

2. 修饰一个方法

语法:

public synchronized void methd() {
    // 方法体
}

以上写法与以下修饰代码块的写法是一样的:

public void method() {
    synchronized(this) {
        // 方法体
    }
}

需要注意的是synchronized关键字在修饰方法时并不能被继承,当子类重写了父类的方法时,同步不在生效。此外,synchronized关键字不能用来修饰接口类的方法和构造方法。

3. 修饰一个静态方法

语法:

public synchronized static void method() {
    // 方法体
}

静态方法又称类方法,它是属于类而非对象的,所以当synchronized修饰静态方法时对类的所有对象都会有效。

4. 修饰一个类

语法:

class ClassName {
    public void method() {
        synchronized(ClassName.class) {
            // 方法体   
        }
    }
}

注意当synchronized关键字修饰一个类时并非是class synchronized CllassName这样的用法,而是类似于修饰代码块时的用法,只不过把synchronized(this)改成了synchronized(ClassName.class),所以作用范围从一个对象实例变为了类的所有对象。也与修饰代码块时类似,对于不用synchronized修饰的部分不会被锁定。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值