线程的同步

更多内容请关注:

Java快速开发学习

锁清秋

有关共享变量的理解可参考:深入分析Java中的关键字static

一、多线程问题

  • 多个线程执行的不确定性引起执行结果的不稳定

  • 多个线程对账本的共享,会造成操作的不完整性,会破坏数据

问题的原因:

当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,另一个线程参与进来执行。导致共享数据的错误。

解决办法 :

对多条操作共享数据的语句,只能让一个线程都执行完,在执行过程中,其他线程不可以参与执行。

二、线程的同步

  • 是利用锁的机制来实现同步的。

  • 锁机制有如下两种特性:

    1. 互斥性:即在同一时间只允许一个线程持有某个对象锁,通过这种特性来实现多线程中的协调机制,这样在同一时间只有一个线程对需同步的代码块(复合操作)进行访问。互斥性我们也往往称为操作的原子性。
    2. 可见性:必须确保在锁被释放之前,对共享变量所做的修改,对于随后获得该锁的另一个线程是可见的(即在获得锁时应获得最新共享变量的值),否则另一个线程可能是在本地缓存的某个副本上继续操作从而引起不一致。

二、Synchronized 的使用方法

一、使用方法

  1. 同步方法

(1) 同步非静态方法

   Public synchronized void methodName(){

        //……
    }

(2) 同步静态方法

Public synchronized static void methodName(){

//……

}
  1. 同步代码块
    synchronized(this|object) {
        //
    }
    synchronized(类名.class) {
        //
    }
    Private final Object MUTEX =new Object();

    Public void methodName(){

    Synchronized(MUTEX ){

      //……

    }

    }

二、根据获取的锁分类

  1. 获取对象锁

    synchronized(this|object) {
     //
    }

    修饰非静态方法

    在 Java 中,每个对象都会有一个 monitor 对象,这个对象其实就是 Java 对象的锁,通常会被称为“内置锁”或“对象锁”。类的对象可以有多个,所以每个对象有其独立的对象锁,互不干扰。

  2. 获取类锁

    synchronized(类名.class) {
     //
    }

    修饰静态方法

    在 Java 中,针对每个类也有一个锁,可以称为“类锁”,类锁实际上是通过对象锁实现的,即类的 Class 对象锁。每个类只有一个 Class 对象,所以每个类只有一个类锁。

在 Java 中,每个对象都会有一个 monitor 对象,监视器:

1) 某一线程占有这个对象的时候,先monitor 的计数器是不是0,如果是0还没有线程占有,这个时候线程占有这个对象,并且对这个对象的monitor+1;如果不为0,表示这个线程已经被其他线程占有,这个线程等待。当线程释放占有权的时候,monitor-1;

2)同一线程可以对同一对象进行多次加锁,+1,+1,重入性


文章作者: 张文军
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 张文军 !
评论