java线程的三种实现以及线程的创建
一、线程的五种状态:
1、新建(new):线程对象被创建后就进入了新建状态。如:Thread thread = new
Thread();
2、就绪状态(Runnable):也被称为“可执行状态”。线程对象被创建后,其他线程调用了
该对象的start()方法,从而启动该线程。如:thread.start(); 处于就绪状态的线程随时可
能被CPU调度执行。
3、运行状态(Running):线程获取CPU权限进行执行。需要注意的是,线程只能从就绪状
态进入到运行状态。
4、阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权限,暂时停止运
行。直到线程进入就绪状态,才有机会进入运行状态。阻塞的三种情况:
1)等待阻塞:通过调用线程的wait()方法,让线程等待某工作的完成。
2)同步阻塞:线程在获取synchronized同步锁失败(因为锁被其他线程占用),它
会进入同步阻塞状态。
3)其他阻塞:通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞
状 态。当sleep()状态超时、join()等待线程终止或超时、或者I/O处理完毕时,线程
重新转入 就绪状态。
5、死亡状态(Dead):线程执行完了或因异常退出了run()方法,该线程结束生命周期。
二、线程状态之间的转换:
三、线程实现的方式:
1、实现Runnable接口
public class MyRunnable implements Runnable{
@Override
public void run() {
System.out.println("MyRunnable");
}
}
使用方式:
public static void main(String[] args) {
//创建自己的Runnable对象
MyRunnable myRunnable = new MyRunnable();
//创建线程,传入Runnable对象
Thread thread = new Thread(myRunnable);
//通过线程的start方法启动线程
thread.start();
}
2、继承Thread类
public class MyRunnable extends Thread{
@Override
public void run() {
System.out.println("MyRunnable");
}
}
使用方式:
public static void main(String[] args) {
//创建自己的Runnable对象
MyRunnable myRunnable = new MyRunnable();
//创建线程,传入Runnable对象
Thread thread = new Thread(myRunnable);
//通过线程的start方法启动线程
thread.start();
}
3、通过Callable和FutureTask实现线程(带返回值)
a:创建Callable接口的实现类 ,并实现Call方法
b:创建Callable实现类的实现,使用FutureTask类包装Callable对象,该
FutureTask对象封装了Callable对象的Call方法的返回值
c:使用FutureTask对象作为Thread对象的target创建并启动线程
d:调用FutureTask对象的get()来获取子线程执行结束的返回值
public class MyRunnable implements Callable<Object> {
@Override
public Object call() throws Exception {
return "ok";
}
}
使用方式:
public static void main(String[] args) throws Exception {
Callable<String> oneCallable = new MyRunnable();
FutureTask<String> oneTask = new FutureTask<String>(oneCallable);
Thread t = new Thread(oneTask);
t.start();
String result = oneTask.get();
System.out.println(result);
}
四、线程run()和start()方法的区别
run()方法是线程具体执行的方法体
start()是线程的启动方法
所以这两个方法还是有本质的区别,希望大家不要搞混了。
五、线程任务的实现和线程创建的区别
在第三点写到的是线程任务实现的方法,其实这个跟多线程是没关系的,通过Runnable、Thread和Callable、FutureTask实现的,其实是线程运行所需要的任务,很多博客写的是线程的创建,其实这是不正确,线程的创建方式其实是通过new关键字实现或者通过线程池来实现
实现方式:
Thread t1 = new Thread(传入任务);
本人小白,如果有哪里不对的或者不合理的,请大家指正