1. 终止线程运行的方式
(1)使用interrupt()方法终止线程
interrupt():为要终止的线程打上停止标记并不会马上停止线程。
interrupted():测试当前线程是否已经是中断状态,
执行后具有清除状态标志值为false的功能。
isInterrupted():测试线程Thread对象是否已经是中断
状态,不清除状态标志。
interrupt()停止线程的正确方法
从上面三种图片可以看出,interrupt()配合interrupted()方法可以做到停止线程,但是不能保证判断之后的代码继续运行,这时需要配合使用return来结束代码继续运行。
(2)使用异常方法停止线程
从上面代码对比interrupt()方法,异常方法可以立即停止当前线程。另外注意,interrupt()方法遇到sleep()方法时会抛出异常,线程停止;
(3)stop()方法暴力停止线程
使用stop停止线程,对锁定的对象进行“解锁”,会导致数据得不到同步的处理,进而出现数据不一致的问题。使用stop()还会释放锁给数据造成不一致性的结果,如果出现这样的情况,则程序处理的数据完全有可能遭到破坏,最终导致程序执行的流程是错误的。
suspend()方法与resume()方法是使线程暂停和恢复运行的两个方法,这两个方法会独占锁,线程在暂停期间不会释放锁,造成资源浪费。同时,如果使用不当,会造成线程安全问题。
yield()方法是使当前线程释放CPU资源,让给其他线程,但是放弃的时间不能确定,可能让出后,马上又抢回来。
2、线程的优先级
在操作系统中,线程可以划分优先级,优先级较高的线程得到CPU资源较多,也就是CPU优先执行优先级较高的线程对象中的任务,其实就是让高优先级的线程获得更多的CPU时间片。优先级具有一下特点:优先级高的线程不一定先执行完、优先级高的线程执行速度更快、优先级高的。
3、synchronized关键字
在方法上加synchronized关键字,编译后在字节码指令中加入了标记flags: ACC_PUBLIC, ACC_SYNCHRONIZED,如果ACC_SYNCHRONIZED存在,则线程需先持有同步锁才能执行方法,完成后释放锁。
而同步代码块则为在锁定的代码前后加上monitorenter和monitorexit来同步方法。
synchronized是可重入锁,“可重入锁“是指自己可以再次获取自己的内部锁。例如,
一个线程获得了某个对象锁,此时这个对象锁还没有释放,当
其再次想要获取这个对象锁时还是可以获取的。
锁重入也支持父子类继承的环境,子类同步方法可以直接调用父类同步方法。
重写方法如果不使用synchronized,则为非同步方法。
synchronized具有锁对象和锁Class文件的两种方式:
(1)对非静态方发使用synchronized,则锁的是当前类的对象实例。