一、Thread和Runnable区别
Java中的thread和runnable都是与线程有关的概念,它们之间有什么区别呢?
thread是一个类,可以扩展Java类库,它在实现线程时必须重写run()方法。而runnable是一个接口,它只有一个run()方法需要重写。在实现线程时,通常使用Runnable接口。
//Thread示例 class MyThread extends Thread{ @Override public void run() { System.out.println("Thread"); } } //Runnable示例 class MyRunnable implements Runnable{ @Override public void run() { System.out.println("Runnable"); } } public class Main { public static void main(String[] args){ //创建Thread对象并启动线程 MyThread myThread = new MyThread(); myThread.start(); //创建Runnable对象并启动线程 MyRunnable myRunnable = new MyRunnable(); Thread thread = new Thread(myRunnable); thread.start(); } }
二、Runnable接口
Runnable接口是一个函数式接口,它只有一个run()方法需要重写,该方法定义了线程要执行的任务的代码逻辑。
实现Runnable接口相对于扩展Thread类更加灵活,因为Java是单继承的,如果扩展了Thread类那么该类就不能再扩展其他的类了,这给程序设计带来了极大的限制。另外,如果需要创建多个线程对象,那么要扩展Thread类需要去创建多个Thread的子类,而实现Runnable接口只需要创建多个Runnable类的实例对象即可。
//Runnable示例 class MyRunnable implements Runnable{ @Override public void run() { for(int i = 0; i < 5; i++){ System.out.println(Thread.currentThread().getName() + ":" + i); try{ Thread.sleep(500); }catch(Exception e){ e.printStackTrace(); } } } } public class Main { public static void main(String[] args){ //创建Runnable对象并启动线程1 MyRunnable myRunnable1 = new MyRunnable(); Thread thread1 = new Thread(myRunnable1, "Thread-1"); thread1.start(); //创建Runnable对象并启动线程2 MyRunnable myRunnable2 = new MyRunnable(); Thread thread2 = new Thread(myRunnable2, "Thread-2"); thread2.start(); } }
三、Runnable状态
线程状态是指一个线程在某一时刻的状态。Java中的线程有以下六种状态:
- New:新建状态,在线程创建后还没有启动时处于此状态
- Runnable:就绪状态,当线程调用start()方法后处于此状态
- Blocked:阻塞状态,线程暂停执行,等待某个条件满足后再继续执行
- Waiting:等待状态,线程等待其他线程的通知,不会自动恢复运行
- Timed Waiting:定时等待状态,线程等待其他线程的通知,等待一段时间后会自动恢复运行
- Terminated:终止状态,线程执行完毕或者抛出异常后处于此状态
Runnable状态是指线程正在执行中的状态。
import java.util.concurrent.TimeUnit; //Runnable示例 class MyRunnable implements Runnable{ @Override public void run() { System.out.println("Runnable线程开始执行。。。"); try{ TimeUnit.SECONDS.sleep(5); }catch(InterruptedException e){ e.printStackTrace(); } System.out.println("Runnable线程执行结束。。。"); } } public class Main { public static void main(String[] args){ MyRunnable myRunnable = new MyRunnable(); Thread thread = new Thread(myRunnable); thread.start(); while(thread.isAlive()){ System.out.println("线程正在执行中。。。"); try{ TimeUnit.SECONDS.sleep(1); }catch(Exception e){ e.printStackTrace(); } } System.out.println("线程执行完毕。。。"); } }
四、Thread和Runnable的选择
一般来说,如果只是简单的单线程程序,可以直接继承Thread类;如果是多线程程序,或者需要继承其他类的情况下,建议采用实现Runnable接口的方式。
Thread类在实现Runnable接口的基础上进行了封装,提供了更多的线程操作方法,适用于需要控制线程的详细信息的高级应用。而Runnable接口则更为简洁,更为灵活。
//Thread示例 class MyThread extends Thread{ @Override public void run() { for(int i = 0; i < 5; i++){ System.out.println(Thread.currentThread().getName() + ":" + i); try{ sleep(500); }catch (InterruptedException e){ e.printStackTrace(); } } } } //Runnable示例 class MyRunnable implements Runnable{ @Override public void run() { for(int i = 0; i < 5; i++){ System.out.println(Thread.currentThread().getName() + ":" + i); try{ Thread.sleep(500); }catch (InterruptedException e){ e.printStackTrace(); } } } } public class Main { public static void main(String[] args){ //创建Thread对象并启动线程 MyThread myThread = new MyThread(); myThread.start(); //创建Runnable对象并启动线程 MyRunnable myRunnable = new MyRunnable(); Thread thread = new Thread(myRunnable); thread.start(); } }
五、总结
Java中的thread和runnable都是与线程有关的概念,其中thread是一个类,可以扩展Java类库,它在实现线程时必须重写run()方法;而runnable是一个接口,它只有一个run()方法需要重写。在实现线程时,通常使用Runnable接口。
Runnable接口相对于扩展Thread类更加灵活,因为Java是单继承的,如果扩展了Thread类那么该类就不能再扩展其他的类了,这给程序设计带来了极大的限制。另外,如果需要创建多个线程对象,那么要扩展Thread类需要去创建多个Thread的子类,而实现Runnable接口只需要创建多个Runnable类的实例对象即可。
线程的状态包括新建状态、就绪状态、阻塞状态、等待状态、定时等待状态和终止状态。Runnable状态指线程正在执行中的状态。
使用Thread类,则需要在类中直接实现run()方法;使用Runnable接口,需要在类中实现run()方法,并且需要创建一个Thread对象,将实现了Runnable接口的类传递给Thread对象的构造方法,并且调用start()方法启动线程。