`

multi-thread(一)基础知识

 
阅读更多

 

 

Thread的五种状态:

        1, new<---------new Thread()

        2, runnable<----thread.start()

        3, running<-----cpu轮流调度

        4, blocked<-----(3种: wait pool,sleep,lock pool(等待syn-lock,等待I/O event))

        5, dead<--------run方法执行完毕,或异常

 

Thread相关的方法

1.sleep(), Thread类的方法,不会释放“锁标志”。剩下的都是Object类的

2.wait()方法

  释放锁,由notifyAll()唤醒,wait,notifyAll是Object的方法,必须在synchronized语句块内,否则IllegalMonitorStateException

3.yield方法

  暂停当前正在执行的线程对象。当前线程重新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行。

  yield()只能使同优先级或更高优先级的线程有执行的机会。

4.join方法

  等待调用join方法的线程结束,再继续执行。如:t.join();//主要用于等待t线程运行结束,若无此句,main则会执行完毕,导致结果不可预测。

5.notifyAll

       唤醒在此对象监视器上等待的所有线程。线程通过调用其中一个 wait 方法,在对象的监视器上等待。 

       直到当前的线程放弃此对象上的锁定,才能继续执行被唤醒的线程。        

        

线程通信,

 

进程通信机制:socket, 文件, shared memory(如何,只有线程才行吧?)信号处理程序(signal handlers)、信号量(semaphores)

 

顺序编程:每一条指令的执行,都有对下一条指令的明确定义。进程有序。

 

线程通信机制:共享内存空间地址(共享对象,变量,通信最容易) + 进程通信机制。 

 

线程两大问题:1线程之间不可见、2线程之间无序。要使得可见+有序(原子),volatile使得可见,单不是原子,可以作为状态控制使用。

 

 

线程的优点:并发执行(不是顺序执行)

        1、使用多CPU

        2、模型的简化

        3、对异步事件的简单处理

        4、用户界面的更加响应性

 

线程的风险:

        1、安全风险:结果不正常,安全意味着:“什么坏事都没有发生”

        2、 liveness(活性,活跃度)风险:liveness意味着:“好事(期望的事)最终肯定会被执行”,

                liveness失败,进程中也有如:if(true){}else{liveness failure}

                线程增加了发生的几率如:死锁,饥饿,活锁。

        3、性能风险:期望的事情尽快的被执行。如:响应速度、吞吐量、可伸缩性。线程会带来context switch的开销。

                考虑分离锁(把一个锁拆分成多个)

 

 

 

2.1线程安全的三种途径:

        1、不跨线程使用共享状态变量:独享地操作本地(基于栈的)变量。

        2、使状态变量不可变

        3、使用同步。

        设计线程安全的类:封装、不可变行、不可变约束。

 

3.1原子性:(相对于复合操作)

        race condition:竞争条件(竞争,争夺共享资源的情况,has several race conditions )

                使用潜在的过期值,决定下一步的操作,,称为check-then-act,(read-wirte)这不是原子操作。不可靠。

 

锁:synchronized提供“独占锁”,保证原子性

        ,volatile,threadLoacl呢?什么锁?

        重进入:线程试图获得它自己占有的锁时,请求会成功,请求基于per-thread,而不是per-invocation

        public calss A{

                public synchronized void doSomething(){...}

        }

        public calss B extends A{

                public synchronized void doSomething(){super.doSomethiong();...}

        }

        如果不可以重进入,B对象调用doSomething时将会死锁

 

 

chapter3 共享对象

        3.1Visibility(可见性,线程A可以始终看见其他线程的对数据执行的结果。)

                一个线程,和一个主线程即可。

                线程不是顺序执行(NoVisibility),会重排序recordering,可以通过synchronized 保证顺序。

                synchronized 可以保证可预见性和原子性。

                volatile变量

                        1、当多个线程使用同一个变量时,每个线程都在其java stack缓冲中有一个这个变量的拷贝,对这个变量的改变实际上是对这个复制品进行改变。而另一个线程在使用这个变量时还可能一无所知。

                        2、volatile变量,不会去假设这个变量的值,每次都重新读取这个变量的值,对变量进行改变时直接作用于主内存。

                volatile只能保证可见性,不能保证“读-改-写”的原子性,不能使i++原子化。

                volatile变量不会被jvm缓存。一般用来做完成、中断的标记。需满足以下条件。线程A的i++,可能被线程B的i++干扰。

                        1、写入变量时不依赖变量的当前值,或者确保只有一个线程操作,i++就依赖当前值,它不需要操作堆内存。

                        2、The variable does not participate in invariants with other state variables; ????????

                        3、Locking is not required for any other reason while the variable is being accessed.??????????

                volatile变量的几个例子(C语言上的):   

                        1). 并行设备的硬件寄存器(如:状态寄存器)   

                        2). 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)   

                        3). 多线程应用中被几个任务共享的变量 

                        区分C程序员和嵌入式系统程序员的最基本的问题。嵌入式系统程序员经常同硬件、中断、RTOS等等打交道,所用不懂得volatile内容将会带来灾难。 

 

 

        3.2. Publication and Escape(发布和逸出)

                Publishing an object means making it available to code outside of its current scope, such as :

                        1、by storing a reference to it where other code can find it, 

                        2、returning it from a nonprivate method, or passing it to a method in another class. 

 

                escaped:        

                        publishing objects before they are fully constructed can compromise thread safety

 

 

线程组是一个可以统一管理的线程集合,默认创建的线程,都属于相同的线程组。

竞争条件:

        accounts[0] += amount;//不是原子操作

        1、将accounts[0]加载到寄存器(java没有寄存器吧?叫pc,只是个名字不同而已)

        2、增加amount

        3、将结果写回accounts[0]

        //aload_0,getfield,iload_2,dup2,执行它们的线程可以在任何一个指令点上被中断。

        C语言-计算机原理

        装载-写入内存--?

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics