1.FutureTask示例代码
FutureTask的get方法是一个阻塞方法,需要等线程代码执行完毕才会接着执行。
FutureTask的 cancel(boolean mayInterruptIfRunning) 方法是中断线程执行的方法,传入false表示不允许中断正在执行的线程,true则表示允许中断。
isCancelled方法表示任务是否被取消成功,如果在任务正常完成前被取消成功,则返回 true。
isDone方法表示任务是否已经完成,若任务完成,则返回true;
get(long timeout, TimeUnit unit)用来获取执行结果,如果在指定时间内,还没获取到结果,就直接返回null。
2.查看线程的方法
windows下: JDK提供的查看java线程的方法jps,杀死进程的方法taskkill /F /PID xxxx
3.线程上下文切换的原因
4.睡眠的线程被唤醒
4.1调用线程的interrupt()方法 如图4-1,
4.2此方法还会打断正在执行的线程,如图4-2。
4.3根据interrupt方法的两阶段终止设计模式如图4-3,因为在执行sleep的时候会清除终止标记所以在catch中重新标记清楚状态为true
4.4 interrupt会影响park方法的执行如图4-4
图4-1,
图4-2
图4-3
图4-4
5.线程睡眠的方法尽量替换成 TimeUnit.SECONDS.sleep(1); 这种方式可读性高一点
6.yield方法
(1).是会把当前调用此方法的线程执行权交出去,会把当前线程从运行状态变成就绪状态。
(2).还是要根据操作系统的调度器来实现,有可能交出去执行权后cup此时比较空闲,那当前线程有可能接着拿到执行权,接着执行。
7.join()方法 等待线程运行结束 主线程等待t1线程运行结束 join(long xxx)方法是限时等待
8.守护线程在主线程结束运行后,也会随之结束运行。
9.线程的状态(java层面是6种状态)
新建,运行,停止,如果线程 调用seelp方法他的状态是 timed waiting ,调用join方法状态是 waiting,竞争锁失败处于阻塞状态是blocked
情况2是 调用了wait方法,会进入Monuitor中的WaitSet集合等待,当调用notify或notifyAll时,线程会进入EntrySet集合进行竞争资源,竞争成功则进入运行状态,失败则是状态9BLOCKED
10.线程安全分析
10.1 局部变量不会存在线程安全问题,因为不同线程调用方法都会创建不同的栈帧不存在数据共享问题,
10.2 方法内引用全局变量也会存在线程安全问题,因为不同线程使用的是同一个值。
10.3 引用暴漏 在子类上覆盖父类方法也可能会出现线程安全问题。
11.常见线程安全类
12.偏向锁:
偏向状态:
Biased就是偏向状态:默认是开启了偏向锁,但是会有延迟如图 12-1 01代表是无锁状态,4秒后打印出结果已经开启了偏向锁结果是101
如图 12-2 添加了参数 -XX:BiasedLockingStartupDelay=0 关闭延迟开启偏向锁,在同步代码块中将线程id写入对象头,在同步代码结束后对象头中依然存在线程id说明当前锁偏向这个id线程。
如图12-3禁用偏向锁参数 -XX:+UseBiasedLocking 此时就会直接从无锁状态升级成轻量级锁。
如图12-4调用对象的hashcode方法就会把偏向的锁退回到无锁状态,因为状态为偏向锁的对象头中没有足够的空间存储hashcode,轻量级锁和重量级锁就不会,因为轻量级锁的hash码会存在栈内存的所记录里,重量级锁会存在Monuitor对象中,解锁的时候会还原回来。
如图12-5偏向锁的撤销,其实就是升级到了轻量级锁,这段代码演示了升级到轻量级锁的过程。
如图12-6批量撤销20次:集合中的对象已经偏向t1了,此时让他批量撤销偏向的操作,偏向到第20回时线程将不会再升级,jvm会进行优化,会让之后的对象都偏向与t2线程不再进行偏向撤销。
如图 12-7批量撤销操作40次:JVM就会觉得自已确实错了,就不该批量偏向,40次之后的默认对象将不再是偏向状态,而是不可偏向状态。
图 12-1
图 12-2
图 12-3
图12-4
图12-5
如图15-6
13.wait/notify
13.1 如图13-1 使用起来注意,如果使用notifyAll的时候要避免虚假唤醒,如果唤醒的不是当前线程,可以使用while循环的方式让其当前线程再次进行等待。
图13-1
原理:
13.2 利用wait/notify 设计 保护暂停模式,该模式的特点就是一对一的生产和消费,
13.3 利用 wait/notify 设计生产者消费者模式,该模式的特点不是一对一的生产和消费,而是多对多,只要生产出了产品消费者竞争到资源就可以进行消费
14.park和unpark
park方法会让线程在执行中进入等待,unpark可以将执行了park方法的线程唤醒,他的特点是不管在park方法执行前后都可以唤醒线程。如图14-1
图14-1
特点:
15.死锁(活跃性)
代码演示:
15.1.查看死锁的工具 打开IDEA Terminal控制台
1.jps查看java相关的线程,再用 jstack 259592 查看线程状态,jvm会自己发现死锁,并给出提示
JVM死锁提示:
2.用jconsole工具来进行查看线程死锁状态。
15.ReentrantLock S
15.1可打断锁是防止其他线程一直未获取到锁












网友评论