zoukankan      html  css  js  c++  java
  • 线程同步

    线程(Thread)是一份独立运行的程序,有自己专用的运行栈。
    线程同步就是线程排队
    共享
    变量
    多个线程访问共享资源的代码有可能是同一份代码,也有可能是不同的代码;无论是否执行同一份代码,只要这些线程的代码访问同一份可变的共享资源,这些线程之间就需要同步。

    同步锁加在代码段上
    public static final Object lock1 = new Object();
    … f1() {
    synchronized(lock1){ // lock1 是公用同步锁
    // 代码段 A
    // 访问共享资源 resource1
    // 需要同步
    }
    }
    … f2() {
    synchronized(lock1){ // lock1 是公用同步锁
    // 代码段 B
    // 访问共享资源 resource1
    // 需要同步
    }
    }

    同一时刻,只有一个线程能够获得lock1的所有权,只有一个线程可以执行代码段A或者代码段B。其他竞争失败的线程只能暂停运行,进入到该同步锁的就绪(Ready)队列。 
    每一个同步锁下面都挂了几个线程队列,包括就绪(Ready)队列,待召(Waiting)队列等。比如,lock1对应的就绪队列就可以叫做lock1 - ready queue。每个队列里面都可能有多个暂停运行的线程。
    注意,竞争同步锁失败的线程进入的是该同步锁的就绪(Ready)队列,而不是后面要讲述的待召队列(Waiting Queue,也可以翻译为等待队列)。
    就绪队列里面的线程总是时刻准备着竞争同步锁,时刻准备着运行。而待召队列里面的线程则只能一直等待,直到等到某个信号的通知之后,才能够转移到就绪队列中,准备运行。


    有的时候,我们希望处理更加复杂的同步模型,比如生产者/消费者模型、读写同步模型等。这种情况下,同步锁模型就不够用了。我们需要一个新的模型。这就是我们要讲述的信号量模型。
    信号量模型的工作方式如下:线程在运行的过程中,可以主动停下来,等待某个信号量的通知;这时候,该线程就进入到该信号量的待召(Waiting)队列当中;等到通知之后,再继续运行。

    (1)等待某个信号量的通知
    public static final Object signal = new Object();
    … f1() {
    synchronized(singal) { // 首先我们要获取这个信号量。这个信号量同时也是一个同步锁
    // 只有成功获取了signal这个信号量兼同步锁之后,我们才可能进入这段代码
    signal.wait(); // 这里要放弃信号量。本线程要进入signal信号量的待召(Waiting)队列
    // 可怜。辛辛苦苦争取到手的信号量,就这么被放弃了
    // 等到通知之后,从待召(Waiting)队列转到就绪(Ready)队列里面
    // 转到了就绪队列中,离CPU核心近了一步,就有机会继续执行下面的代码了。
    // 仍然需要把signal同步锁竞争到手,才能够真正继续执行下面的代码。命苦啊。 … }
    }
    需要注意的是,上述代码中的signal.wait()的意思。signal.wait()很容易导致误解。signal.wait()的意思并不是说,signal开始wait,
    而是说,运行这段代码的当前线程开始wait这个signal对象,即进入signal对象的待召(Waiting)队列。

    (2)发出某个信号量的通知
    … f2() {
    synchronized(singal) { // 首先,我们同样要获取这个信号量。同时也是一个同步锁。
    // 只有成功获取了signal这个信号量兼同步锁之后,我们才可能进入这段代码
    signal.notify(); // 这里,我们通知signal的待召队列中的某个线程。
    // 如果某个线程等到了这个通知,那个线程就会转到就绪队列中
    // 但是本线程仍然继续拥有signal这个同步锁,本线程仍然继续执行
    // 嘿嘿,虽然本线程好心通知其他线程,
    // 但是,本线程可没有那么高风亮节,放弃到手的同步锁
    // 本线程继续执行下面的代码
    … } }
    需要注意的是,signal.notify()的意思。signal.notify()并不是通知signal这个对象本身。而是通知正在等待signal信号量的其他线程。

    有40条有深度的分析在这个链接里 http://www.cnblogs.com/aishangJava/p/6860309.html





  • 相关阅读:
    Java程序运行机制及开发环境
    Redis源码分析(八)--- t_hash哈希转换
    Redis源码分析(八)--- t_hash哈希转换
    Redis源码分析(八)--- t_hash哈希转换
    Redis源码分析(九)--- t_list,t_string的分析
    Redis源码分析(九)--- t_list,t_string的分析
    Redis源码分析(九)--- t_list,t_string的分析
    Redis源码分析(十)--- testhelp.h小型测试框架和redis-check-aof.c日志检测
    Redis源码分析(十)--- testhelp.h小型测试框架和redis-check-aof.c日志检测
    Redis源码分析(十)--- testhelp.h小型测试框架和redis-check-aof.c日志检测
  • 原文地址:https://www.cnblogs.com/CuiHongYu/p/6867475.html
Copyright © 2011-2022 走看看