java并行编程书籍_java-实战java高并发程序设计-ch2java并行程序基础

java并行程序基础

2.1 有关线程, 需要知道的事

进程是线程的容器

线程状态图:

827a283ff2f77b8139e1509ff42f848c.png

2.2 线程的基本操作

2.2.1新建线程

2.2.2终止线程

stop 暴力终止线程,废弃方法

8f9797ca0c7bbd9afe66f418d1012262.png

d2520a98b94976f5231f8b719d92b67a.png

2.2.3线程中断

方法:

9fd689a44b5fc7ceab17c7100bb2d868.png

8f6e097d0c8f39896f62816a002da822.png

2.2.4 等待(wait)和唤醒notify

注意:

wait 是object的一个方法,调用wait方法的对象,必须在synchronized 中,因为要获取它的监视器。

wait会释放锁

public class SimpleWN {

final static Object obj = new Object();

public static void main(String[] args) {

Thread t1 = new Thread(new Runnable() {

@Override

public void run() {

synchronized(obj) {

System.out.println("t1.start,and t1 will wait");

try {

// 调用wait 方法的这个对象必须被synchronizeed

//wait 会释放锁

obj.wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("t1 was notify");

}

}

});

Thread t2 = new Thread(new Runnable() {

@Override

public void run() {

synchronized(obj){

System.out.println("t2 start and will notify t1");

// 调用notify 方法的这个对象必须被synchronizeed

//如果 有n个线程此时都是由于调用了obj.wait方法,那么会唤醒任意一个

obj.notify();

try {

Thread.sleep(2000);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("t2 end run");

}

}

});

t1.start();

t2.start();

}

}

输出:注意锁

t1.start,and t1 will wait

t2 start and will notify t1

t2 end run

t1 was notify

2.2.5 挂起(suspend)和继续执行(resume)

suspend()和resume方法

c56d7350b6d1325fc62c1eb2015cce71.png

86118b52a59961dae0e1289a23a161dd.png

2.2.6 join 和yeild

join:加入,把线程当做一个方法了。

yeild:让出线程执行权,但是还是会争夺线程的执行权

eb8f6592bc82e48a90945f716d427e47.png

2.3 volatile 与java 内存模型(JMM)

JMM: 原子性,可见性,有序性

原子性:32位虚拟机中多线程读写long不会有问题,但是不能保证i++

可见性:

虚拟机在-server模式下会进行优化,下面的程序永远不会跳出。

/**

* @author ChengBing Han

* @date 9:39 2018/6/22

* @description

*/

public class NoVisibility {

private static boolean ready;

private static int number;

private static class ReaderThread extends Thread {

public void run() {

/*

while (!ready){

System.out.println(new Date());

}*/

//这个和上述的优化不同,这个在-server模式下会优化

while (!ready) ;

System.out.println(number);

}

}

public static void main(String[] args) throws InterruptedException {

//永远不会终止程序

new ReaderThread().start();

Thread.sleep(1000);

number = 42;

ready = true;

Thread.sleep(2000);

}

}

备注:上述ready 用volatile 修饰后就会退出,或者用-client 模式启动虚拟机

9fc07def73c98ec45528b493f87d29cb.png

337580e10dcd1ae5fa58c6b99c9d67f9.png

2.4 分门别类的管理 线程组

2.5 驻守线程的后台:守护线程

2.6 线程优先级:先干重要的事

1-10,优先级逐渐升高

2.7 synchronized(内部锁)

volatile 可以保证原子性,和可见性,但是如果两个线程同时修改了某个变量,那么还是无法识别的,这时volatile的局限性。所以需要synchronized等来确保

b59de1efd541be8b139085fa88d9bf7d.png

2.8 程序中隐蔽的错误

2.8.1 没有提示的错误e

比如两个正数int 相加, 溢出导致 其值为负数。

2.8.2 并发下的ArrayList

两个线程同时对一个ArrayList add 对象,每个线程add 10000 个对象, 最终结果

可能1:ArrayList 中有2万个对象。

可能2:抛出异常

ArrayList 内部结构被破坏了

dd2a2d400b84d4188a6add1a89ffeaaa.png

a82239caabbf654feb00a8d1ed949cd5.png

可能3:ArrayList 中的对象个数小于2万

b84fe81fe6fa66c8453870da8eebcb17.png

2.8.3 并发下的HashMap

两个线程同时对HashMap添加对象,每个线程add 10000 个对象,最终结果

可能1:HashMap 中有2万个对象。

可能2:对象个数少于2万

可能3:HashMap内部结构发生破坏,程序无法终止,cpu会被大量消耗。

2.8.4 错误加锁

static Integer i = 0;

.........

synchronized(i){

i++;

}

//问题在于, integer是不可变的,所以每次i++都会创建一个新的对象。可以用javap 反编译查看

允许多个线程同时访问:信号量

允许几个线程访问

9f41b08a3322d3eb045d70bd2dd292e2.png

6b4aea47c8177aaa5dbb0500e0939258.png

de1bc8a39fc501693537233c0f5b314a.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值