基本概念不多做介绍。
线程创建
两种方法:
1 | public class MyThread extends Thread{ |
1 | public class MyRunnable implements Runnable{ |
可以看出最明显的区别是上者多线程需要创建多个对象,而下者可以使用一个对象,这样就可以在MyRunnable中定义数据,多个线程共享,再者,java”单继承,多实现”,故下者还可以继承其他类进行扩展,所以下者用的多一些。
线程守护
可以把线程守护理解为保镖,用它去保护其他线程,若其他线程结束或者中断,那它也没有存在的意义,会被强制终止。
1 | t2.setDaemon(true); //设置t2为守护线程 |
线程中断
线程中断需要使用
1 | t1.interrupt(); |
但是需要注意的是此时并没有真正的中断该线程,只是将这个线程的中断状态的布尔值进行了修改,要想真正中断
1 | if(interrupted()) {//若当前线程被设置为中断状态 |
也就是中断前给线程一个留“临终遗言”的机会,交代完“后事”才可以真正被中断。
直接杀死线程的stop方法已经被弃用。
线程生命周期
https://blog.csdn.net/lonelyroamer/article/details/7949969
线程安全
什么是线程安全:多个线程同时要修改一个变量的时候,引起冲突
线程安全问题解决
1
2
3synchronized(对象){//锁住某个对象,如果这个对象已经被锁定,那么等待。
//TODO
}//执行完之后,归还钥匙1
2
3
4
5
6
7
8
9private ReentrantLock lock = new ReentrantLock();
………………
lock.lock();//加锁
try {
//TODO
}
} finally {
lock.unlock();
}
出现线程安全问题的地方,要锁同一个对象(可以是当前对象,也可以单独创建一个对象)
锁住某个对象,如果这个对象已经被锁定,那么停止当前线程的执行,一直等待,一直等到对象被解锁。
(保证同一个时间,只有一个线程在使用这个对象)
创建同步方法
同步方法锁的是哪个对象呢?锁定的是当前对象this
另补充:线程安全的类
- 安全: StringBuffer Vector
- 不安全:StringBuilder ArrayList
死锁问题
死锁是这样一种情形:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。
形象化例子:吃饭需要同时使用刀叉,一个人拿叉等刀,另一个人拿刀等叉。
产生举例:
1 | class Thread1 implements Runnable{ |
这样两个进程都卡住等待
1 | 输出: |
解决方案:将两个线程取锁的顺序换为一样
1 | class Thread2 implements Runnable{ |
线程组
线程组ThreadGroup 默认处于同一个组里面
使用线程组可以统一设置这个组内线程的一些东西。比如设置优先级,设置是否是守护线程。
1 | MyRunnable r = new MyRunnable(); |
定时器
作用:一种工具,线程用其安排以后在后台线程中执行的任务。可安排任务执行一次,或者定期重复执行。
使用类:Timer(定时器)和TimerTask(定时器启动之后要执行的任务)
timer.schedule(TimerTask task, long delay)
timer.schedule(TimerTask task, long delay, long period)
timer.schedule(TimerTask task, Date time)
timer.cancel();
注:转载文章请注明出处,谢谢~