前言
最近学习了java基础之多线程,感觉还是很nice,毕竟基础薄弱。所以总结一下,加深印象的同时留以备用。
正文
多线程的实现
实现方式有三种:
1.实现Runnable接口和它的run方法
2.继承Thread类实现它的run方法
3.实现Callable接口和它的call方法
三种线程实现的区别:
继承Thread和实现Runnable接口优先级不用说,肯定优先实现Runnable接口,毕竟类只能继承一个父类。
接口Runnable和Callable的区别:
Runnable接口的run方法不能抛出异常并且没有返回值,而Callable接口是可以做到抛出异常和返回值。
Callable接口的实现更加复杂,能做的事情更多,高并发使用的多,基本的使用选择Runnable即可。
/**
* @author jjh
*/
public class TerminateThread implements Runnable{
public boolean isFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
private boolean flag = true;
@Override
public void run() {
while (flag){
System.out.println(Thread.currentThread().getName()
+ " is running!");
}
}
public static void main(String[] args) throws InterruptedException {
TerminateThread thread1 = new TerminateThread();
new Thread(thread1).start();
Thread.sleep(1000);
thread1.setFlag(false);
}
}
Lambda
多线程的线程体可以使用Lambda进行适当简化,Lambda并非适用所有线程。java8 Lambda表达式的使用
线程的状态和方法
线程有新生、就绪、运行、阻塞、死亡五种状态,Java Thread类包含了State枚举类,State有6个对象标识状态:
1.NEW
尚未启动的线程处于此状态。
2.RUNNABLE
在Java虚拟机中执行的线程处于此状态。
3.BLOCKED
被阻塞等待监视器锁定的线程处于此状态。
4.WAITING
正在等待另一个线程执行特定动作的线程处于此状态。
5.TIMED_WAITING
正在等待另一个线程执行动作达到指定等待时间(超时)的线程处于此状态。
6.TERMINATED
已退出的线程处于此状态。
他们分别对应的关系有:
新生状态 ---> 1.NEW
就绪状态 ---> 2.RUNNABLE
运行状态 ---> 2.RUNNABLE
阻塞状态 ---> 3.BLOCKED、4.WAITING 、5.TIMED_WAITING
死亡状态 ---> 6.TERMINATED
线程进入就绪状态的四种情况:
1.start方法,线程创建后调用start方法进入就绪状态。
2.解除阻塞状态时,线程重新进入就绪状态。
3.yield中断方法,线程让出CPU的调度,重新进入就绪状态,注意不进入阻塞状态。
yield方法让当前线程重新进入到就绪状态重新等待CPU调度执行,
存在cpu下一次又调度了此线程的情况,
所以yield方法执行后并非一定是其他线程进入运行状态,也有可能又是此线程。
4.JVM从本地线程切换到其他线程,则当前线程进入到就绪状态。
带来阻塞的四种情况:
1.sleep方法,进入休眠,同时占用着资源。
2.wait方法,和sleep一样,但是并不占用资源。
3.join方法,插队,有插队就有阻塞。
3.IO等操作带来的阻塞。
使线程进入死亡状态的方法:
stop和destory方法,目前都不推荐使用,
可以使用外部boolean变量flag进行标示,在run方法里面while(flag)来达到
控制线程内执行体的执行,从而代替stop方法。例如上面实现线程的例子。
线程的方法:
常用的方法:
Thread.sleep(...) 使线程休眠一段时间,线程依旧会抱着资源睡觉。
Thread.currentThread() 获取当前线程
其他方法:
setPriority(int newPriority) 设置线程的优先级
上面也介绍了一些使线程进入某些状态的方法,不重复介绍了。
线程的优先级
优先级:
java提供一个线程调度器来监控程序中启动后进入就绪状态的所有线程,
线程调度器按照线程的优先级决定应调度哪个线程来执行。
优先级低意味获得调度的概率低,并不是绝对先调用优先级高后调用优先级低的线程。
//启动线程之前设置优先级
t5.setPriority(Thread.MAX_PRIORITY);
//启动线程
t1.start();
优先级包含:Thread.MAX_PRIORITY(10)、Thread.MIN_PRIORITY(1)
、Thread.NORM_PRIORITY(5)。
也可直接指定1-10的数字,从1到10,优先级依次上升。
守护线程:
守护线程Daemon:
守护线程是为用户线程服务的,JVM不用等待守护线程执行完成。
线程默认都是用户线程。JVM需要等待用户线程结束才会停止。
//设置为守护线程
t.setDaemon(true);
t.start();