Thread类和Runnable接口
两者都可以实现多线程,那么两者的区别和联系有哪些?
Thread类的定义。
public class Thread extends Object implements Runnable
从Thread类的定义可以清楚的发现,Thread类也是Runnable接口的子类,但是Thread类中并没有完全地实现Runnable接口中的run()方法,
区别:如果一个类继承Thread类,则不适合于多个线程共享资源,而实现了Runnable接口,就可以方便地实现资源的共享。
范例:继承Thread不能共享资源
package ThreadDemo01; class MyThread2 extends Thread { private int ticket = 5; public void run() { // 覆写Thread类的run()方法 for (int i = 0; i < 100; i++) { if (ticket > 0) { System.out.println("买票:tick=" + ticket--); } } } } public class ThreadDemo04 { public static void main(String[] args) { MyThread2 mt1 = new MyThread2();// 创建线程对象1 MyThread2 mt2 = new MyThread2();// 创建线程对象2 MyThread2 mt3 = new MyThread2();// 创建线程对象3 mt1.start();// 启动线程1 mt2.start();// 启动线程2 mt3.start();// 启动线程3 } }
结果:
买票:tick=5
买票:tick=4
买票:tick=3
买票:tick=2
买票:tick=1
买票:tick=5
买票:tick=4
买票:tick=3
买票:tick=2
买票:tick=1
买票:tick=5
买票:tick=4
买票:tick=3
买票:tick=2
买票:tick=1
范例:Runnable可以实现资源共享
package test1; class MyThread implements Runnable { private int ticket = 5; public void run() { for (int i = 0; i < 100; i++) { if (ticket > 0) { System.out.println("买票:ticket=" + ticket--); } } } } public class ThreadDemo02 { public static void main(String[] args) { MyThread mt1 = new MyThread(); // 创建线程对象 new Thread(mt1).start(); new Thread(mt1).start(); new Thread(mt1).start(); new Thread(mt1).start(); new Thread(mt1).start(); new Thread(mt1).start(); new Thread(mt1).start(); // 启动了7个线程 } }
结果:
买票:ticket=5
买票:ticket=4
买票:ticket=3
买票:ticket=2
买票:ticket=1
虽然启动了7个线程,但是指卖出了五张票
使用Runnable的好处是:
1.适合多个相同程序代码的线程去处理同一资源的情况
2.可以避免由与java的单继承特性带来的局限性
3.增强了程序的健壮性,代码能够被多线程共享代码与数据独立