前段时间学习到多线程相关内容了,看了java多线程编程核心这本书,下面是小编对这本书的总结
【第一章:技能】
1.多线程是异步的,代码的执行顺序不是线程的执行顺序,线程被调用是随机的
2.多次调用start()会出现异常 IllegalThreadStateException 属于IO异常吗?
属于runtime异常!
3.currentThread()返回当前代码段正在被哪个线程调用的信息~
4.isAlive()判断当前线程是否处于活动状态
5.sleep()在指定的毫秒数内让当前"正在执行的线程"休眠
6.getId()取得线程的唯一标识
7.yield()放弃当前的cpu资源,将它让给其它任务去占用,但是放弃时间不确定~
7.停止线程
run自动停止退出
stop强行停止
会抛出java.lang.ThreadDeath异常,不需要显式捕捉
interrupt方法中断线程(调用并没有真正停止,先sleep再调用该方法)
与return结合实现停止if(this.isInterrupted){return;}
8.暂停
Suspend()暂停 resume()恢复
缺点:独占(使得公共对象独占情况)
不同步:暂停导致数据不同步
9.线程优先级
setPriority()1-10个优先级
MIN_PRIORITY = 1
NORM_PRIORITY = 5
MAX_PRIORITY = 10
优先级的继承性,A线程启动B线程,B线程的优先级与A是一样的当优先级差距过大时,与代码的调用关系无关了(具体业务可能会引起资源不存在情况,比如a方法执行需要b方法中给公共变量赋值,应该先调用b,但是当a的优先级太高的时候就需要注意了!!!)
【第二章:对象变量并发访问】
1.synchronized 同步的 关键字,代表加锁 排队进行
asynchronized 异步的
volatile 易变的,不稳定的 关键字,类型修饰符
2.方法内部私有变量,为线程安全的
实例变量,非线程安全
多个对象,多个锁
3.共享资源的读写访问才有必要被同步化,否则不需要同步化
4.脏读:在读取实例变量时,此值已经被其它线程更改过了
5.可重入锁:自己可以再次获取自己的内部锁(如:有一条线程获取了某个对象的锁,此时这个对象锁还没有释放,当其再次想要获取这个对象的锁的时候还是可以获取的,如果不可以锁重入的话,就会造成死锁)
6.同步不具有继承锁(同步不可以继承)
7.同步代码块解决同步方法的弊端:用关键字锁定本类的部分代码块,让其它代码进行异步执行
synchronized(this)是锁定的当前对象
8.synchronized和synchronized(this)两种作用
调用呈现阻塞状态
同一时间是有一个线程可恶意执行该锁定的代码
9.用synchronized锁非this对象,其它方法与该锁定内为异步,提高效率
10.synchronized加到静态方法上是给class类上锁(可以对所有对象实例上锁) 我要锁定一个类如何做?
加到非静态方法上是给对象上锁 我要锁定类的实例如何做?
11.一般不用String作为锁对象(避免常量池带来的问题), 改用new object() 因为不放入缓存中
12.死循环带来的问题(while(true){}),用同步代码块来解决问题
13.通过jdk自带的工具来检测是否有死锁
进入cmd 进入jdk的bin目录下,执行jps 得到运行线程的id
再执行jstack -1(L) 3244
volatile作用,使得变量在多个线程间可见,但是不能保证原子性
【第三章:线程间通信】
1.wait/notify机制
2.Join(long)的功能是在内部使用wait(long)方法来实现的,它具有释放锁的特点
3.threadLocal的使用
全局存放数据的盒子,每个线程set进去的值都不同
第一次get到的值是null,通过继承重写initialValue方法修改第一次get的值
InheritableThreadLocal的使用
可以在子线程中取得父线程继承下来的值
【第四、五章:Lock,Timer使用】
1.ReentrantLock类
嗅碳锁定,多路分支通知功能
Private Lock lock = new ReentrantLock()
Lock.lock();
Lock.unlock();
2.使用Condition实现等待
Private Condition condition = lock.newCondition();
Condition.await();
这样会报错,必须在调用await之前调用lock.lock(),否则会出现IllegalMonitorStateException
3.object: wait() == Condition 中的await()
Notify() Signal()
notifyAll() signalAll()
4.Condition对象可以唤醒部分指定线程,有助于提升线程的运行效率
通过调用多个condition来进行等待和唤醒
5.生产者消费者,一对一打印,通过hasValue判断是否有线程
6.拿到锁是随机的所以也就不存在公平的情况
7.一些常用的方法
1.计划任务的功能,指定时间内执行某一任务
2.TimerTask多个任务的延时
3.schedule(TierTask task,Date firstTime,long period) 该方法的作用是在指定的日期之后,按指定的间隔周期性地无限循环地执行某一任务
4.TimerTask类的cancel()方法:将自身从任务队列中清除
5.Timer类的cancel()方法:将任务队列中的全部任务清空
注意:有时并不一定会停止执行计划任务,而是正常执行
6.schedule(TimerTask task,long delay) :当前的时间为参考时间,在此时间基础上延迟指定的毫秒数后执行一次TimerTask任务
7.schedule(TimerTask task,long delay,long period):方法的当前时间为参考时间,在此时间基础上延迟指定的毫秒数,再以某一间隔时间无限次数地执行某一任务
8.scheduleAtFixedRate(TimerTask task,Date firstTime,long period) :如果执行任务的时间没有被延时,那么下一次任务的执行时间参考的是上一次任务的结束时的时间来计算
【第六章:单例】
1.延时加载在多线程中是错误的,不能实现保持单例的状态
2.通过synchronized关键字解决延时加载错误的问题(效率非常低下)
3.用同步代码块实现,(效率低下)
4.针对性单独枷锁(只对实例化的代码枷锁,提高了效率)
5.使用DCL双检查锁机制
【第七章:拾遗增补】
1.验证:new(线程序列化之后还从未执行start()方法时的状态)
2.runnable 线程进入运行时状态
3.Terminated 线程被销毁时的状态
4.timed_waltlng :代表执行了thread.sleep方法,呈现等待状态
5.Blocked :某一个线程在等待锁的时候
6.Waiting :执行了object.wait()方法的时候
7.线程组:可以批量的管理线程或线程组对象,有效地对线程或线程组对象进行组织
一级关联:父对象中有子对象,但是不创建孙对象
多级关联:父对象中有子对象,子对象中再创建子对象
【总结】
通过思维导图的形式,然后看书的时候,将里面关键的地方找出来,然后组内讨论的时候进行深入的剖析,最终收获的还是很给力的~