zoukankan      html  css  js  c++  java
  • java核心学习(二十三) 多线程---线程同步

    一、线程安全问题

      线程安全问题是由于代码在执行中的非原子性导致的。如果不能在程序上对线程访问临界区做出控制,则会“偶然出错”。

    二、同步代码块

      同步监视器,实际上就是要访问的临界区,这个临界区是一个对象,下面代码obj就是同步监视器,在执行下面的代码时,会先获取obj的对象锁,如果该锁已经被其他线程占用,则当前线程阻塞。取得了对象锁之后就可以执行同步代码块里的代码,相当于PV原语中的互斥锁。

      

    synchronized(obj)
    {
    
        //对临界区obj进行访问的代码
    }

    三、同步方法

      在方法返回值定义之前使用sychronized关键字修饰,相当于同步监视器为this对象的同步代码块。

      使用同步方法可以很方便的实现线程安全的类,比如StringBuilder线程不安全,StringBuffer线程安全。

    四、什么时候释放同步监视器的锁定

      代码无法显示释放,但是以下几种情况会导致线程释放对同步监视器的锁定:

    •     当前线程的同步方法、同步代码块执行结束,当前线程即释放同步监视器;
    •     当前线程在同步代码块遇到了break、return终止了该代码块、该方法的继续执行,当前线程会释放同步监视器;
    •     当前线程在同步代码块发生异常或错误,导致该代码块或该方法结束,会释放同步监视器;
    •     当前线程在执行同步代码块或同步方法时,程序执行了同步监视器对象的wait()方法,则当前线程暂停,并释放同步监视器;

      下面两种情况,线程不会释放同步监视器

    •   线程执行同步代码块或同步方法时,程序调用 Thread.sleep()、Thread.yield()方法来暂停或让步当前进程
    •   线程执行同步代码块时,其他线程调用了该线程的suspend()方法将该线程挂起,该线程不会释放同步监视器

    五、同步锁(Lock)

      java5开始,可以通过显式定义同步锁对象(Lock)来实现同步,这种同步机制比简单的声明同步代码快更为灵活,线程开始访问临界区之前先获得Lock对象。

      java5中对同步锁设计了两个根接口Lock、ReadWriteLock(读写锁,可以解决读者写者问题,而读写锁在同一时刻可以允许多个读线程访问,但是在写线程访问时,所有的读线程和其他写线程均被阻塞。读写锁维护了一对锁,一个读锁和一个写锁,通过分离读锁和写锁,使得并发性相比一般的排他锁有了很大提升。),并为Lock提供了ReentrantLock(可重入锁,可重入是指对于同一个锁对象,如果该线程已经获取该锁对象,则再次进入被该锁对象锁住的区域时依然可以进入)实现类,为ReadWriteock提供了ReentrantReadriteLock实现类。

      Synchronized实际上是一种可重入锁,通常会使用可重入锁来控制线程并发访问临界区。

      ReentrantLock锁具有可重入性,也就是说,一个线程可以对已被加锁的ReentrantLock锁再次加锁,ReentrantLock对象和会维持一个计数器来追踪lock()方法的嵌套调用,线程在每次调用lock()加锁后,必须显示调用unlock()来释放锁,所以一段被锁保护的代码可以调用另一个被相同锁保护的方法。

      

  • 相关阅读:
    pyzabbix 接口使用
    lvs使用进阶
    lvs基础
    linux服务基础之nginx配置详解
    linux服务基础之编译安装nginx
    iptables (二) nat & tcp_wrapper
    iptables (一) 主机防火墙和网络防火墙
    rsyslog及loganalyzer
    linux基础之Mini Linux制作
    linux基础之磁盘管理与文件系统
  • 原文地址:https://www.cnblogs.com/Theshy/p/7574547.html
Copyright © 2011-2022 走看看