多线程学习备忘

同步,异步,阻塞,非阻塞 http://kalogen.iteye.com/blog/670841

同步:所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回。线程一直占着cpu
异步: 异步的概念和同步相对。当一个异步过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的部件在完成后,通过状态、 通知和回调来通知调用者。

阻塞:阻塞调用是指调用结果返回之前,当前线程会被挂起。 和同步的区别是等待时线程挂起了,不占用cpu

非阻塞: 非阻塞和阻塞的概念相对应,指在不能立刻得到结果之前,该函数不会阻塞当前线程, 而会立刻返回和异步的区别是完成了它也不会接到通知,它是等下再主动过来看看

1.1 Brief History of Concurrency

1.three motivating factors of thread:
Resource utilization:当有一个程序在等待比如输入输出操作时,为了高效可以让另一个程序去执行它的任务。
Fairness: 程序对机器资源的使用应该是平等的。
Convenience:通常写几个小的程序,每个小的程序执行一个小的任务。比只写一个大的程序,把所有的任务都归为自己完成要好。

2.modern operating systems treat thread, not processes, as the basic units of schedule.

3.Since threads share the memory address space of their owning process, all threads within a process have access to the same variables and allocate objects from the same heap.

=================================================
1.2 Benefits of Threads

1. Exploiting multiple process: since the basic unit of scheduling is the thread, a program with only one thread can run on at most one processor at a time. But, with multiple threads, these threads can run on multiple processors.

2. simplicity of modeling: 这里搞清除task和thread的区别,一个task是指要完成的一项任务。在一个时间段专心于一项任务往往比较简单,相反,如果要管理优先权和deadline和task间的切换阿,就比较麻烦了,我们的目标是a program that processes one type of task sequentially, don't managing mulitple different tasks at once.然后用多个thread(在一个process里)去完成同一个task。
==================================================
1.3 Risks of Threads
NotThreadSafe:
    /** Returns a unique value. */

    public int getNext() {

        return value++;

    }


所谓原子操作,可以简单理解成一步(一起)完成的。要不不完成,要不一起完成,不能完成一半又被其他thread侵入。

value++不是原子操作,是分拆成三步的,read the value, add one to it, and write out the new value.

ThreadSafe: 多了一个synchronized
 public synchronized int getNext() {

        return nextValue++;

    }


race condition:危险,程序执行的结果正确与否 主要是依赖于threads的执行的时间顺序(由操作系统调度)。

多线程的冒险:
1.safety hazard:刚才这个getNext()例子,race condition.
2.liveness hazard: an activity gets into a state such that it is permanently unable to make forward progress.比如死锁deadlock,饿死starvation
3.performance hazards: threads scheduling carry some degree of runtime overhead, and other compiler optimizations.etc.
=========================
Chapter 2 Thread Safety
1. an object's state is its data, stored in state variables such as fields. 可以简单认为object的状态就是它的变量

1.writing thread-safe code is, as its core, about managing access to state, and in particular to shared, mutable state.

2. shared: mean that a variable could be accessed by multiple threads.
mutable:可变的意思。

3.一个object需不需要是thread-safe取决于这个object会不会在其lifetime被multiple threads access. Making an object thread-safe requires using synchronization to coordinate access to its mutable state

4. if multiple threads access the same mutable state variable without appropriate synchronization, your program is broken, there are three ways to fix it:
(1)don't share the state variables across threads
(2)make the state variable immutable(不可变的)
(3)use synchronization whenever accessing the state variable.
====================================================
2.1 what is thread safety
1.definition: a class is thread-safe if it behaves correctly when accessed from multiple threads, regardless of the scheduling or interleaving of the execution of those threads by the runtime environment(无论threads执行的顺行,怎样穿插,结果都正确), and with no additional synchronization or other coordination on the part of the calling code(不用调用这个class object的程序synchronization也程序运行正确).

2. thread-safe classes encapsulate any needed synchronization so that clients need not provide their own.

3.stateless objects are always thread-safe.(看例子listing 2.1). stateless的含义: it has no fields and references no fields from other classes. The transient state for a particular computation exists solely in local variables that are stored on the thread's stack and are accessible only to the executing thread.(放在 函数里定义的变量都是local variables, 是存在thread栈里的,只能被当前的thread访问)
================================
2.2 Atomicity
1. atomic: an action is atomic means that it does not execute as a single, indivisible operation, relative to other operations on the same sate.比如a++不是atomic的,因为其实是三步去执行

2. the most common type of race condition is check-then-act, 这种往往你check的时候是最新的,但跳到act的时候就不是最新的了,因为check和act之间是有时间差的。一个经典的例子见Listing 2.3
another common race condition is : read-modify-write: a++

3.compound actions: sequences of operations that must be executed atomically in order to remain thread-safe.like read-modify-write, check-then-act.

4.Listing 2.4介绍了一个thread-safe class:AtomicLong. 看一个class是否是thread-safe,主要是看它的state是否是access safe,像例子里 这个Class的state就是AtomicLong object: count,因为count是thread-safe,所以这个Class也是thread-safe
=========================================================
2.3 Locking
synchronized (lock) {

    // Access or modify shared state guarded by lock

}


1.only one thread at a time can execute a block of code guarded by a given lock, the synchronized blocks guarded by the same lock execute atomically with respect to other threads.

2. A synchronized method is a shorthand for a synchronized block that spans an entire method body, and whose lock is the object(也就是this) which the method is being invoked(static synchronized methods use the Class object for the lock) 一般不推荐这样做,因为lock的是this,其它lock也是this的其他线程的block或者method就不能执行了(同一个线程的还是可以执行的,见4)

3.The lock is automatically acquired by the executing thread before entering a synchronized block and automatically released when control exits the synchronized block.

4. Reentrancy
当一个线程threadA request a lock,这个lock已经被其它线程threadB拿住,则threadA block to wait the threadB released the lock.当一个线程ThreadA request a lock, 这个lock已经被它本身ThreadA拿住,则它的request lock成功,它可以执行被这个lock synchronized 的block(只要它是同一个线程的)

对每一个线程,它会对lock进行计数,如果同一个线程还是request它拿住的lock,则计数+1,如果一个被这个线程的lock synchronized 的block退出,就减1,其它线程要等到这个线程的lock变为0为止。

看英文书和例子
===============================================
2.4 Guarding state with locks

1.有一个误区,只有在 writing the shared variables的时候才需要synchronized,其实这是错的,在 的时候, 任何access 这个 shared variable 的时候都需要synchronized。这个也很容易理解,否则一个线程writing了一个shared variable,另一个线程同时去读它,结果可能读到的就是旧的值.

2.接上面,而且对于同一个shared variable, 必须synchronized 同一个锁

总结起来: for each mutable state variable that may be accessed by more than one thread, all accesses to that variable must be performed with the same lock held. in this case, we say that the variable is guarded by that lock.

3. For every invariant that involves more than one variable, all the variables involved in that invariant must be guarded by the same lock.
    BigInteger[] factors = factor(i);//i和factors是一致的

             lastNumber.set(i);//这步和下一步要在同一个锁里

             lastFactors.set(factors);

=============================================
2.5 liveness and performance
主要是看List2.8的这个例子
理解:1.synchronized最好不是方法级别的,这样它的范围太广了,影响性能,对于这个synchronized方法来说相当于顺序执行(见Figure2.1)
2.一个函数的synchronized可以分为几段,相关联的shared state要同一个lock
3.在函数内定义的状态variable并不需要synchronized
4. 最好synchronized的是计算时间不长的部分. 比如例子中factors = factor(i)是对i进行分解,对于一个大的数i是十分耗时的,而这里i和factor都是method里定义的local variable,不需要synchronized

2.avoid holding locks during lengthy computations or operations not completing quickly such as networking or I/O
===============================================
Chapter3: sharing Ojects

synchronization also has another significant, and subtle, aspect:
memory visibility. we want not only to prevent one thread from modifying the state of an object when another is using it, but also to ensure that when a thread modifies the state of an object, other threads can actually see the changes that were made.

In order to ensure visibility of memory writes across threads,you must use synchronization.
================================================
3.1 visibility:
1。看Listing 3.1的例子,有两个线程, ReaderThread 和main函数的thread, 在这个例子中main函数对number 和 ready的改变可能ReaderThread根本看不到(因为没用Synchronized)

2.注意一点,在两个线程中有一些shared data的时候,如果不用synchronized把两个线程同步起来,则一个线程对shared data的改变对于另一个线程来说是 无法预知的,可以是可见,也可能不可见,即拿到的有可能是以前的旧值。

3.看Listing 3.1的例子,它有说虽然在main程序中 number是比ready 先赋值的,但是在readerThread中它可能已经见到ready更新为true,但是number还是旧值(stale data): reordering.  a thread can see an up-to date value of one variable(对应ready) but a stale value of another variable(对应例子中的number) that was written first.

4.看Figure3.1 visibility Guarantees for synchronization. 理解这句话:everything A did in(如例子中的x) or prior to(如例子中的y,在block之前定义) a synchronized block is visible to B when it executes  a synchronized block guarded by the same lock.

Locking is not just about mutual exclusion, it is also about memory visibility. To ensure that all threads see the most up-to-date values of shared mutable variables, the reading and writing threads must synchronized on a common lock.

5.理解volatile variables:看书3.1.4.很容易理解 weaker form of synchronization: volatile variable. 接上个例子Listing 3.1(和ready比较), a read of a volatile variable always returns the most recent write by any thread.

6. 还有解释可见的那段: the values of all variables that were visible to A prior to writing to the volatile variable become visible to B after reading the volatile variable.(和synchronized一样)但是不推荐用volative变量来控制 其他shared变量在多线程中的可见性。

7.一个有用的例子: Listing 3.4 解析了volatile 变量比上面Listing 3.1的ready好的作用

8. Locking can guarantee both visibility and atomicity, volatile variables can only guarantee visibility.

你可能感兴趣的:(thread,多线程,Access,UP,performance)