美文网首页
[Java]线程和锁

[Java]线程和锁

作者: DrunkPian0 | 来源:发表于2017-12-09 19:07 被阅读19次

    0x00 线程调度

    线程调度指的是系统为线程分配CPU使用权。分为两种:

    1. 协同式线程调度
      线程想用CPU多久就用多久,用完了才让给别的线程。实现简单,但容易发生进程阻塞。
    2. 抢占式线程调度
      可以用yield()让出使用权。并且可以设优先级。即便一个线程阻塞了,也不会导致进程阻塞。

    0x01 (对象的)线程安全

    指的是并发访问对象时不会进行额外的同步操作。比如Immutable的对象就是线程安全的。

    0x02 线程安全的实现方法

    1. 互斥同步(Mutual Exclusion & Synchronization)

    又称阻塞同步。
    同步是指多个线程并发访问共享数据时,保证同一时刻共享数据只被一个(使用信号量时对应:一些)线程使用。
    互斥是手段,同步是目的。
    在Java中,最基本的互斥同步手段就是synchronized关键字(除了synchronized之外,还可以使用ReentrentLock,重入锁)。

    synchronized关键字在编译后会行程moniterenter和moniterexit两个字节码指令,这两个指令需要一个reference类型的参数来指明要加锁和解锁的对象。如果synchronized明确指定了对象参数,就用这个对象作为锁对象(所以会看到声明一个成员变量的数组作为锁对象);如果没有明确指定,就根据synchronized修饰的是实例方法还是类方法,取对应的对象实例或者Class对象作为锁对象。

    有点像GC的引用计数算法

    在Java中,每个class都有一个相应的Class对象。也就是说,当我们编写一个类,编译完成后,在生成的.class文件中,就会产生一个Class对象,用于表示这个类的类型信息。

    注意:

    synchronized是一个重量级(heavyweight)的操作。

    Java的线程是映射到操作系统的原生线程上的,阻塞或唤醒线程都需要CPU时间,帮助用户态和内核态之间转换,对于简单的同步块,有可能状态转换的时间比执行的时间还长。

    0x02 非阻塞同步

    从处理问题的方式上说,互斥同步属于一种悲观的并发策略。
    随着硬件指令集的发展,我们有了另外一个选择:基于冲突检测的乐观并发策略,通俗地说,就是先进行操作,如果没有其他线程争用共享数据,那操作就成功了;

    如果共享数据有争用,产生了冲突,那就再采取其他的补偿措施(最常见的补偿措施就是不断地重试,直到成功为止),这种乐观的并发策略的许多实现都不需要把线程挂起,因此这种同步操作称为非阻塞同步(Non-Blocking Synchronization)。

    Ref:
    http://blog.csdn.net/truelove12358/article/details/54963791
    http://blog.csdn.net/qinjienj/article/details/7578582

    相关文章

      网友评论

          本文标题:[Java]线程和锁

          本文链接:https://www.haomeiwen.com/subject/wsqpixtx.html