关于Java线程的几个问题
1.线程是什么?
线程:线程是代表一个应用程序所执行的某项子任务,一个进程包含了无数个线程。
多个线程同时交替抢占CPU资源,可以提高CPU的利用率,能有更好的用户体验。
2.实现线程的方式
Java中实现线程的方法有三种:
a、继承Thread类,重写run()方法。代码如下:
public class MyThread extends Thread{
@Override
public void run() {
System.out.println("我是一个线程");
}
}
这样就可以通过创建MyThread类的对象创建一个线程:
public static void main(String[] args) {
MyThread thread = new MyThread();
}
b、实现Runnable接口,重写run()方法。代码如下:
class MyRunnable implements Runnable{
@Override
public void run() {
System.out.println("我是一个线程");
}
}
这样就可以通过实现了Runnable接口的类来创建线程。
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();//不是线程,只是线程的实现逻辑
Thread thread = new Thread(myRunnable);
}
c、利用线程池:线程池里面存放多个线程节省了创建线程的时间,增加了空间。用以空间换时间的方式提供效率。
3.线程的常用方法:
a、Thread.currentThread:这是Thread类的静态方法,表示获取当前进程。
b、start():启动一个线程。
c、setName/getName:用于设置和获取线程名称。
d、sleep:Thread类的静态方法,可以让线程进入休眠,会出现检查性异常。
e、wait:这是Object类的方法,会直接让线程进入阻塞状态,会释放对象锁。如果没有人唤醒,会一直处于阻塞状态,唤醒的方法就是notify和notifyAll。
f、setPriority:设置线程优先级1-10,默认值是5,值越高,优先级越高。
g、yield:放弃当前CPU执行权,进入就绪状态(可能下一次CPU执行权还被选中,这个只是提供一种可能)。
h、t.join:等待t线程执行结束后,才能执行当前线程。
i、isAlive:判断线程是否存活。
sleep、wait、join在使用时都会出现检查性异常:线程终止异常
备注:
run()和start()的区别
run()开启表示只有一个主线程去执行,像一个正常的方法执行顺序。
start()开启,表示多线程执行,主线程和子线程交替执行。
4.线程状态:
线程状态:五大状态
创建状态:当使用new操作,创建线程new Thread(),此时线程处于创建状态。
就绪状态:一个情况下,一个创建状态线程不会自动开始,要执行线程必须调用start()方法来启动线程,启动之后也并不会立即执行。而会与其他线程去抢占CPU,只有抢到了CPU的线程,才会进入运行状态。
运行状态:当线程抢到了CPU,会进行运行状态,真正执行run()方法
阻塞状态:线程运行过程中,可能由于各种原因进入阻塞:a、线程调用了sleep方法,进入休眠。b、线程调用了wait,需要等待特定触发条件(唤醒)。c、线程得到了一个锁,而该锁正在被其他线程持有,其他线程不释放锁,该线程也会处于阻塞。d、线程调用了IO操作会被阻塞,因为该操作需要输入输出,如果不是输入输出会一直处于阻塞。总结:阻塞状态,正在运行的线程并没有结束,只是暂时让出CPU。
死亡状态:导致线程死亡的原因有两种:a、run()方法正常执行到结束,自然死亡。b、执行线程时出现异常导致了终止run(),病死的。
注:interrupt():中断线程