• Java 的同步、异步


    2018-01-03

    因为线程的运行与休眠,是由操作系统控制的,存在很大的随机性。因线程不安全而造成的bug,每次出现的时间,产生的现象都可能不同,因此往往很难定位。所以在写多线程的程序时,一定要确保自己的代码是线程安全的。

    一、同步 synchrony

    在多线程程序中,为了防止因多个线程随机修改同一个变量,而引入锁机制,实现线程间的同步。

    ReentrantLock类(reentrant可重入的),实现了 lock 接口。

    1. 同步格言:**如果从一个变量读值,而这个变量可能是之前被其他线程修改了的,或者,向一个变量写入值,而这个变量接下来可能被其他线程读取。那么必须确保这个操作是同步的(synchronous)。 **

    2. 确保同步的方法:

      1. 首选是使用 java.util.concurrent 包中的线程安全的机制来自动处理同步。

      2. 使用 synchronized 关键字 修饰线程不安全的方法 / 构造同步代码块。

      3. 内部锁Lock与内部条件Condition:实例的 Synchronized 方法,实际上是使用了this对象做为锁。如果用这个Runnable对象创建了多个线程,任意线程调用这个方法时,会先试图获取这个this对象锁。离开时会先释放this锁。(而静态的 sync 方法使用 的锁,则是其所从属的class对象。)

      4. Synchronized 代码块:将传入的对象做为锁

      5. 使用 Volatile 关键字 修饰线程不安全的变量(译:反复无常的)

      6. Lock 和 Condition,因为锁与条件都对程序员开放,被认为更不安全。所以一般建议只在需要使用多个Condition时,才使用它。(sync方法只有一个内部condition)

    3. 线程安全的条件:如果出现了问题,一定是两个条件中的一个不满足。

      1. 需要同步的线程必须使用的是同一把锁。否则后来的线程不会因此被阻塞。
      2. 所有线程不安全的代码(即 c. 中所言的操作代码)都已经是同步的了。
    4. 死锁:

    二、异步 asynchrony

    大部分语言都是通过 coroutine 实现的异步,Java 本身目前并没有很好的异步工具。

  • 相关阅读:
    Django基础——Form&Ajax篇
    redis--悲观锁、乐观锁
    redis--事务
    redis--三种特殊数据类型---的简介、用法
    redis--zet(有序集合)---常用命令、场景
    redis--hash(哈希)---常用命令、场景
    redis--set(无序集合)--的常用命令,应用
    redis--(队列)list--常用命令、小结
    redis--string(字符串) --常用命令、应用场景
    redis基本知识
  • 原文地址:https://www.cnblogs.com/kirito-c/p/10306323.html
Copyright © 2020-2023  润新知