多线程:synchronized 关键字用法(修饰类,方法,静态方法,代码块)

27 篇文章 3 订阅

多线程:synchronized 关键字用法(修饰类,方法,静态方法,代码块)


synchronized用法

synchronized修饰的对象有几种:

  • 修饰一个类:其作用的范围是synchronized后面括号括起来的部分,作用的对象是这个类的所有对象

  • 修饰一个方法:被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象

  • 修饰一个静态的方法:其作用的范围是整个方法,作用的对象是这个类的所有对象

  • 修饰一个代码块:被修饰的代码块称为同步语句块,其作用范围是大括号{}括起来的代码块,作用的对象是调用这个代码块的对象


修饰一个类

其作用的范围是synchronized后面括号括起来的部分,作用的对象是这个类的所有对象,如下代码:

class ClassName {
   public void method() {
      synchronized(ClassName.class) {
         // todo
      }
   }
}

修饰一个方法

synchronized 修饰一个方法很简单,就是在方法的前面加synchronized,例如:

public synchronized void method()
{
   // todo
}

另外,有几点需要注意:

  • 在定义接口方法时不能使用synchronized关键字。

  • 构造方法不能使用synchronized关键字,但可以使用synchronized代码块来进行同步。

  • synchronized 关键字不能被继承 。如果子类覆盖了父类的 被 synchronized 关键字修饰的方法,那么子类的该方法只要没有 synchronized 关键字,那么就默认没有同步,也就是说,不能继承父类的 synchronized。


修饰静态方法

我们知道 静态方法是属于类的而不属于对象的 。同样的, synchronized修饰的静态方法锁定的是这个类的所有对象 。如下:

public synchronized static void method() {
   // todo
}

修饰代码块

  • 当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。

  • 当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。

  • 尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。

  • 第三个例子同样适用其它同步代码块。也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。

  • 以上规则对其它对象锁同样适用.


ps

修饰静态方法其实是类锁,区别于对象锁。

public ClassA {
    public synchronized static void staticMethod() {
    // todo
}

public synchronized void method() {
    // todo
}

public void method2() {
synchronized(ClassA.class) {
            // todo
        }
    }
}

ClassA obj = new ClassA();

也就是说ClassA.staticMethod() 和 obj.method() 并不会存在互斥关系,但是会和obj.method2()存在互斥关系。


pps

在平时多线程的使用中,特别是关于自己定义一些东西的遍历和添加的时候,最好保证在遍历的时候不要添加,在输出数据的同时不要添加数据,因为多线程机智,你无法控制输出输入在同一个线程的话,最好使用锁机制,来避免一些错误的产生。

  • 15
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
synchronizedJava 中用于实现线程同步的关键字。它可以用在方法代码块上,作用分别如下: 1. synchronized 作用在上:定的是该的 Class 对象。 ```java public class MyClass { public static synchronized void myMethod() { // ... } } ``` 在这个例子中,myMethod() 方法是静态的,使用 synchronized 关键字修饰,表示该方法在调用时会定 MyClass 的 Class 对象。因为 Class 对象在 JVM 中只有一份,所以该方法被多个线程同时调用时,只有一个线程能够获得,其他线程需要等待。 2. synchronized 作用在方法上:定的是该方法所属的对象实例。 ```java public class MyClass { public synchronized void myMethod() { // ... } } ``` 在这个例子中,myMethod() 方法是实例方法,使用 synchronized 关键字修饰,表示该方法在调用时会定该方法所属的对象实例。因为每个对象实例在 JVM 中都有自己的,所以该方法被多个线程同时调用时,每个线程会定自己所属的对象实例,因此不会产生冲突。 3. synchronized 作用在代码块上:定的是该代码块所属的对象实例。 ```java public class MyClass { public void myMethod() { synchronized (this) { // ... } } } ``` 在这个例子中,使用 synchronized 关键字修饰了一个代码块,该代码块所属的对象实例就是 this。因为每个对象实例在 JVM 中都有自己的,所以该代码块被多个线程同时执行时,每个线程会定自己所属的对象实例,因此不会产生冲突。 总结来说,synchronized 关键字可以用于方法代码块上,它们的作用分别是的 Class 对象、方法所属的对象实例和代码块所属的对象实例。根据具体的应用场景,选择不同的定方式可以更好地实现线程同步。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值