参考:
https://github.com/chengbingh...java
进程是线程的容器
线程状态图:git
2.2 线程的基本操做
2.2.1新建线程
2.2.2终止线程
stop 暴力终止线程,废弃方法github
2.2.3线程中断
方法:多线程
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
2.2.6 join 和yeild
join:加入,把线程当作一个方法了。
yeild:让出线程执行权,可是仍是会争夺线程的执行权优化
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
1-10,优先级逐渐升高
2.7 synchronized(内部锁)
volatile 能够保证原子性,和可见性,可是若是两个线程同时修改了某个变量,那么仍是没法识别的,这时volatile的局限性。因此须要synchronized等来确保
2.8.1 没有提示的错误e
好比两个正数int 相加, 溢出致使 其值为负数。
2.8.2 并发下的ArrayList
两个线程同时对一个ArrayList add 对象,每一个线程add 10000 个对象, 最终结果
可能1:ArrayList 中有2万个对象。
可能2:抛出异常
ArrayList 内部结构被破坏了
可能3:ArrayList 中的对象个数小于2万
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 反编译查看
容许多个线程同时访问:信号量
容许几个线程访问