多线程之Thread VS Runnable

今天看了慕课网教学视频,学习了Thread和Runnable之间的区别,虽然之前也有接触过,但是总是不够深入,看了知识点然后再以博客记录之,必会记忆更深刻,理解上也会更上一层楼。

一. 构建线程的两种方式

1.继承Thread类

class MyThread1 extends Thread{
	public void run() {
		// TODO Auto-generated method stub
		
	}
}
public class ThreadTest{
	public static void main(String[] args){
		MyThread1 mt=new MyThread1();
		mt.start();
	}
}

2.实现Runnable接口

class MyThread2 implements Runnable{

	@Override
	public void run() {
		// TODO Auto-generated method stub
		
	}
	
}
public class RunnableTest {
	public static void main(String[] args){
		MyThread2 mt=new MyThread2();
		Thread thread=new Thread(mt);
		thread.start();
	}
}

以上是创建线程的两种方式,而且两种方式中启动线程稍有不同。继承Thread方式中,直接new Thread子类即可,而实现Runnable接口方式中,先new 实现的接口类,再定义一个Thread对象,把之前的接口类通过传参方式传进去。

二. 两种创建线程的区别

首先,因为Java中类的继承只能采用单继承的方式,如果采用继承Thread方式创建线程,那么这个线程类将不能再继承其他类,这个这个方法的局限性。相反,Java允许实现多个接口,采用Runnable接口方式,线程类还可以继承其他类和实现其他接口。

上面的区别是两种方式比较明显的区别,是显而易见的,其实这两种方式还有另外的区别,Runnable方式可以共享访问资源。这个听起来比较拗口,也不能一下子明白说的是什么意思,还是拿代码来说明问题。

举个例子,火车站中卖票的例子,假设火车站有3个窗口卖5张票。

先采用Thread方式。

class MyThread1 extends Thread{
	private int count=5;
	private String name;
	public MyThread1(String name){
		this.name=name;
	}
	public void run() {
		// TODO Auto-generated method stub
		while(count>0){
			count--;
			System.out.println(name+"卖出1张票,还剩余"+count);
		}
	}
}
public class ThreadTest{
	public static void main(String[] args){
		MyThread1 mt1=new MyThread1("窗口1");
		MyThread1 mt2=new MyThread1("窗口2");
		MyThread1 mt3=new MyThread1("窗口3");
		mt1.start();
		mt2.start();
		mt3.start();
	}
}
输出结果如下:

窗口1卖出1张票,还剩余4
窗口3卖出1张票,还剩余4
窗口3卖出1张票,还剩余3
窗口3卖出1张票,还剩余2
窗口3卖出1张票,还剩余1
窗口3卖出1张票,还剩余0
窗口2卖出1张票,还剩余4
窗口2卖出1张票,还剩余3
窗口2卖出1张票,还剩余2
窗口2卖出1张票,还剩余1
窗口2卖出1张票,还剩余0
窗口1卖出1张票,还剩余3
窗口1卖出1张票,还剩余2
窗口1卖出1张票,还剩余1
窗口1卖出1张票,还剩余0

通过结果可以看出,每个窗口都卖出了5张票,也就是各个窗口之间并没有共享车票的信息,显然这种方式是不能用来卖票的。


采用Runnable方式。

class MyThread2 implements Runnable{
	private int count=5;
	@Override
	public void run() {
		// TODO Auto-generated method stub
		while(count>0){
			count--;
			System.out.println(Thread.currentThread().getName()+"卖出1张票,还剩余"+count);
		}
	}	
}
public class RunnableTest {
	public static void main(String[] args){
		MyThread2 mt=new MyThread2();
		Thread thread1=new Thread(mt,"窗口1");
		Thread thread2=new Thread(mt,"窗口2");
		Thread thread3=new Thread(mt,"窗口3");
		thread1.start();
		thread2.start();
		thread3.start();
	}
}
执行结果为:

窗口1卖出1张票,还剩余4
窗口1卖出1张票,还剩余3
窗口1卖出1张票,还剩余2
窗口1卖出1张票,还剩余1
窗口1卖出1张票,还剩余0

由此可见各个线程间是共享资源的,即票源。通过这个实例,相信大家也就明白了Thread和Runnable的第二个不太显而易见的区别。


阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页