1 如何实现Java多线程?
1.1.继承Thread类,重写run()方法
Thread类本质上是实现了Runnable接口的一个实例。
Class MyThread extends Thread{
public void run()
{
System.out.println(“Thread body”);
}
}
public class Test{
public static void main(String[] args){
MyThread thread=new MyThread ();
thread.start();//开启线程
}
}
1.2.实现Runnable接口,并实现该接口的run()方法
Class MyThread implements Runnable{
public void run()
{
System.out.println(“Thread body”);
}
}
public class Test{
public static void main(String[] args){
MyThread thread=new MyThread ();
Thread t=new Thread(thread);
t.start();//开启线程
}
}
启动线程:start()-启动一个新线程,并执行线程中的run方法。但是调用后并不是立即执行多线程代码,而是让该线程变为可运行态(Runnable),什么时候运行代码由操作系统决定。
1.3.实现Callable接口,重写call()方法
最终还是通过Thread的对象的API来控制线程。
该接口和Runnable接口的功能类似,但提供了比Runnable更强大的功能:
- 在任务结束后可以有个返回值
- Call()方法可以抛出异常
- 可以拿到一个Future对象,检查进程是否完成,使用该对象的get方法获取线程结束的返回值。
Class MyThread implements Callable<String>{
public String call() throws Exception
{
return “Hello world!”;
}
}
public class Test{
public static void main(String[] args){
ExecutorService threadPool=Executors.newSingleThreadExecutor();
Future<String> future=threadPool.submit(new MyThread ());//启动
System.out.println(future.get());
}
}
以上三种方式中,前两种方式线程执行完后都没有返回值,只有最后一种是带返回值的。当需要实现多线程时,推荐使用实现Runnable接口的方式。
2.Thread和Runnable的关系
Thread是实现了Runnable接口的类,使用run支持多线程
因类的单一继承原则,推荐多使用Runnable接口
3 run方法和start方法的区别?
系统通过线程类的start()方法来启动一个线程,此时该线程处于就绪状态,意味着这个线程可以被JVM来调度执行。在调度过程中,JVM通过调用线程类的run()方法来完成实际的操作,当run()方法结束后,此线程就会终止。
直接调用线程的run()方法,就是一个普通的函数,程序还是只有一个线程。
start()方法能够异步地调用run()方法,只有通过调用线程类的start方法才能真正达到多线程的目的。
start方法会去调用JVM的StartThread方法去创建一个子线程,并去调用run方法