持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第13天,点击查看活动详情
进程是操作系统分配资源的单位,线程是调度的基本单位,线程之间共享进程资源。
利用多线程技术可以使系统同时运行多个程序块,缩短出程序响应的时间,提高计算机资源的利用率,达到多任务处理的目的。
线程的五种状态:1、新建状态(New),2、可运行(Runnable),3、运行状态(Running),4、阻塞状态(Blocked);,5、死亡状态(Dead)。
线程状态
新建状态
线程对象被创建后,就进入了新建状态,此时线程尚未启动。
可运行状态
线程对象被创建后,调用该对象的start()方法,从而来启动该线程。启动之后,线程处于可运行状态,随时可能被CPU调度执行。
运行状态
当线程获取了CPU时间片,就处于运行转态,执行程序代码。
阻塞状态
当线程由于某种原因放弃了CPU的使用权就会暂停运行,直到线程进入可运行状态才有机会转到运行状态,一般情况下,阻塞有下面三种情况:
- 等待阻塞:调用运行状态的线程的wait()方法,JVM会把该线程放入等待队列中。
- 同步阻塞:运行状态的线程在获取synchronized同步锁的时候如果锁被其它线程所占用,就会获取锁失败,它会进入同步阻塞状态。
- 其他阻塞:调用了运行状态线程的sleep()方法或者join()方法时,线程会进入阻塞状态。
死亡状态
线程执行完了或者因异常退出,从而结束了线程的生命周期。
使用线程
继承 Thread 类
创建自定义类并继承 Thread 类。然后重新run()方法编写业务代码。
class ThreadTest extends Thread{
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}
启动线程需要使用start()方法,而不是run()方法。
new ThreadTest().start();//Thread-0
new ThreadTest().start();//Thread-1
new ThreadTest().run();//main
通过start()方法才能启动线程,从而抢占CPU资源,当线程被调度的时候会自动执行run()方法,而当我们直接调用run()方法的时候,仅仅是当做普通对象执行。
实现 Runnable 接口
创建自定义类并实现 Runnable 接口。然后重新run()方法编写业务代码。
class RunnableTest implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}
RunnableTest对象并不能直接使用,还需要创建Thread对象,然后当RunnableTest对象注入到Thread对象中,最后调用start()开启线程。
new Thread(new RunnableTest()).start();//Thread-0
new Thread(new RunnableTest()).start();//Thread-1
new RunnableTest().run();//main
由于Java不支持多重继承,如果使用方式一继承Thread创建线程,就无法继承其他类,所以一般有限选择实现Runnable接口。