上班之后发现自己真是渣,最近不忙好好学习。。在网上下载的《七周七并发模型》,配合书中的讲解和课后问题,做下笔记。
Day1:
其中,第二篇文章中,对DCL的分析,线程2在第一次判断instance == null时,得到instance对象,并不等同于instance对象已经完全创建完成并且将内部成员初始化完成,new一个对象的过程并不是原子的,简单来说,可以分为几个步骤,1 分配内存空间 2 创建空的对象 3 初始化空的对象 4 完成对象引用指向,由于这几个步骤处理器可能并发执行,比如3,4 并发执行,所以在new操作完成之后,对象不一定马上初始化完成,所以在get方法的时候,内部成员的值可能还未初始化。这也是第二篇分析的DCL的漏洞原因。
Day2:
2. java线程虚假唤醒
3. volatile与AtomicIntegerfieldupdater 区别与关系
4. 高级并发编程学习-atomic包学习(重点介绍AtomicInteger、AtomicIntegerFieldUpdater)
对于虚假唤醒,除了2中那种情况,如果调用signalAll/notifyAll的话,会唤起多个线程,而各自线程不再检查,也会抛出异常。
package signalAllTest;
import java.util.ArrayList;
import java.util.List;
public class NotifyAllTest {
static class MyStack {
private List<String> list = new ArrayList<String>();
public synchronized void push(String value) {
synchronized (this) {
list.add(value);
System.out.println("Produce run! value is " + value);
notifyAll();
}
}
public synchronized String pop() throws InterruptedException {
synchronized (this) {
if (list.size() <= 0) {
wait();
}
System.out.println("Consumer run!");
return list.remove(list.size() - 1);
}
}
}
// 生产者
static class Produce implements Runnable {
private MyStack exp;
public Produce(MyStack exp) {
this.exp = exp;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
exp.push("i is " + i);
}
}
}
// 消费者
static class Consumer implements Runnable {
private MyStack exp;
public Consumer(MyStack exp) {
this.exp = exp;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
try {
exp.pop();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
MyStack exp = new MyStack();
Produce produce = new Produce(exp);
Consumer consumer = new Consumer(exp);
new Thread(produce, "线程A").start();
new Thread(consumer, "线程B").start();
new Thread(consumer, "线程C").start();
}
}
运行结果:
Produce run! value is i is 0
Consumer run!
Consumer run!
Exception in thread "线程C" java.lang.ArrayIndexOutOfBoundsException: -1
at java.util.ArrayList.elementData(ArrayList.java:418)
at java.util.ArrayList.remove(ArrayList.java:495)
at signalAllTest.SignalTest$MyStack.pop(SignalTest.java:25)
at signalAllTest.SignalTest$Consumer.run(SignalTest.java:63)
at java.lang.Thread.run(Thread.java:748)
Produce run! value is i is 1
Consumer run!
Produce run! value is i is 2
Consumer run!
……
Day3
1. Java并发编程:CountDownLatch、CyclicBarrier和Semaphore 这篇文章真的大赞!
2. 阿姆达尔定律:S=1/(1-a+a/n) S加速比,a为并行所占比例,n是并行节点个数,理论上,a越接近于1,n越大,加速比越高