第一章 Java多线程技能
1.1进程/线程/多线程
进程:受操作系统管理的基本运行单位,即操作系统中正在运行的exe程序。
线程:在进程中独立运行的子任务。
1.2
实现多线程方法:1.继承Thread 2.实现Runnable接口
1.继承Thread
Thread.start():通知”线程规划器“此线程已经准备就绪,等待调用线程对象的run()。即让系统安排一个时间来调用run()。使得其具有异步执行效果。
Thread.run():同步执行,此线程对象不是由”线程规划器“处理,而是由main主线程来调用run(),即必须等run()执行完后才可以执行下面的代码。
线程对象的构造方法是被main线程调用的,而run方法是被Thread-0的线程调用的,它是自动调用的方法。
注意在 MyThread t = new MyThread();Thread t = new Thread(c)时,此时得到的t1是Thread.currentThread,是一个新的线程,而this则表示的仍然是MyThread的引用,二者是不一样的。
1.4 isAlive()方法
作用:判断当前线程是否处于活动状态。
活动状态:指线程已经启动且尚未终止,即执行.start()方法后,到线程终止的这一段时间。
1.5 sleep()方法
作用:在指定的毫秒数内让当前的”正在执行的线程“休眠(暂停执行)
1.6 getId()方法
作用:取得线程的唯一标识
1.7 停止线程
1.停止方法:三种,1,使用退出标志,当run方法完成后线程终止;2,使用stop方法强行终止,不推荐,其与suspend,reesume为过期方法,不安全且已废弃;3,使用interrupt方法中断线程。
关于Thread.interrupt:https://www.zhihu.com/question/41048032
若在for循环内,检测到已经intterrupt,并break出循环,但循环外的语句仍会执行,避免此情况,可以在for内主动抛出一个exception来让线程终止。
1.7.3 能停止的线程--异常法
虽然线程已停止,但仍会执行下面的语句,此时只要在判断线程已终止后抛出异常,就不会再执行后面的语句了。
1.7.4 在沉睡中停止
如果在sleep状态下停止某一线程,会进入catch语句,并且清除停止状态值,使之变成false。
1.7.5 暴力停止--使用stop()方法
注意:线程的停止应由线程主动完成,而不应由外界来造成。因为可能会导致一些请理性的工作无法完成,以及数据不一致。
关于此方法的危害:https://blog.youkuaiyun.com/jiangwei0910410003/article/details/19900007
1.7.8 使用return停止线程
return和interrupt()配合使用,但仍建议抛异常+interrupted(),可使得线程停止的事件向上传播。
(stop()抛出的ThreadDeath还不用显式捕获,悄无声息地就挂了)
1.9 yield()方法
向调度程序发出当前线程愿意让出CPU的提示,调度程序可以忽略。 即,此种让CPU的行为时间是不确定的,且可以被忽略。
1.10 线程优先级
1.setPriority()来设置;2.具有继承性(子类与父类优先级一致)3.高优先级的线程只是意味着有更大机率获得CPU,优先级与代码执行顺序无关。(即随机性,优先级高的线程不一定先执行完)
1.11 守护线程
当所有非守护线程全部完成,守护线程会自动销毁。
1.12 Thread.suspend()和Thread.resume()
已废除的方法,容易导致死锁。参考blog的问题:https://blog.youkuaiyun.com/jiangwei0910410003/article/details/19910517
第二章
2.1.1 局部变量线程安全
方法内部的变量是私有的,不存在线程安全的问题。因为其存在栈中,为线程所私有,方法运行完即销毁。 只有实例变量才为线程共有,其存在堆中。
2.1.6 synchronized锁重入
1.自己可以再次获取自己的锁。即在一个synchronized方法/块的内部调用本类的其他synchronized方法/块时,是永远可以得到锁的。若不可重入锁,就会造成死锁。
2.当存在父子类继承关系时,子类完全可以通过“可重入锁”调用父类的同步方法。
2.1.7 出现异常,锁自动释放。
2.1.8 同步不具有继承性
2.2 synchronized同步块
应用场景:用关键字synchronized声明方法,若A线程调用同步方法执行一个长时间任务,则B线程必须较长时间。此时可以用synchronized同步语句块来解决。
2.2.2 同步代码块的使用(只在必须同步的地方使用)
当两个并发线程访问同一个对象object中的同步代码块时,一段时间内只能有一个线程被执行,另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。
2.2.4 一半同步,一半异步
不在块中的就是异步,在块中的就是同步执行。
2.2.5 synchronized代码块