java-实战java高并发程序设计-ch2java并行程序基础

java并行程序基础

参考:
https://github.com/chengbingh...java

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

进程是线程的容器
线程状态图:git

clipboard.png
2.2 线程的基本操做
2.2.1新建线程
2.2.2终止线程
stop 暴力终止线程,废弃方法github

clipboard.png
clipboard.png

2.2.3线程中断
方法:
clipboard.png多线程

clipboard.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方法ide

clipboard.png

clipboard.png

2.2.6 join 和yeild
join:加入,把线程当作一个方法了。
yeild:让出线程执行权,可是仍是会争夺线程的执行权
clipboard.png优化

2.3 volatile 与java 内存模型(JMM)

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

可见性:
虚拟机在-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 模式启动虚拟机code

clipboard.png

clipboard.png

2.4 分门别类的管理 线程组

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

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

1-10,优先级逐渐升高

2.7 synchronized(内部锁)
volatile 能够保证原子性,和可见性,可是若是两个线程同时修改了某个变量,那么仍是没法识别的,这时volatile的局限性。因此须要synchronized等来确保


clipboard.png

2.8 程序中隐蔽的错误

2.8.1 没有提示的错误e
好比两个正数int 相加, 溢出致使 其值为负数。

2.8.2 并发下的ArrayList
两个线程同时对一个ArrayList add 对象,每一个线程add 10000 个对象, 最终结果
可能1:ArrayList 中有2万个对象。
可能2:抛出异常
ArrayList 内部结构被破坏了
clipboard.png
clipboard.png

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

clipboard.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 反编译查看

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

容许几个线程访问

clipboard.png

clipboard.png

clipboard.png

相关文章
相关标签/搜索