`
chaijuntao
  • 浏览: 22844 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Java多线程-基础(Runnable篇)

 
阅读更多

上一讲中我们提到了继承Thread类是实现多线程的一种方式,那么现在就来看看第二种方式:Runnable接口。

废话少说,上代码(依旧是之前的例子):

public class ThreadDemoOne implements Runnable {
	
	int no,workno,sleeptime;
	public ThreadDemoOne(int no,int workno,int sleeptime) {
		// TODO Auto-generated constructor stub
		this.no = no;
		this.workno = workno;
		this.sleeptime = sleeptime;
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		try {
			for(int i=0;i<5;i++){
				System.out.println("Thread["+no+"] do work "+workno+"_"+i);
				Thread.sleep(1000);
			}
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	public static void main(String[] args) throws InterruptedException {
		System.out.println("Main do work 1");
		new Thread(new ThreadDemoOne(1,2,1000)).start();
		System.out.println("Main do work 3");
		Thread.sleep(1000);
		System.out.println("Main do work 4");
		new Thread(new ThreadDemoOne(2,5,1000)).start();
		Thread.sleep(1000);
		System.out.println("Main do work 6");
	}
}

 

乍一看貌似一样啊,请仔细看(红色代码部分),是的,区别就是这么小!

有人就有疑问了,oracle是不是吃饱了撑的(sorry,骂错了,当时还是SUN公司推出的多线程),为什么好端端要提供两种差不多的多线程实现方式呢?

 

不着急骂Java脑残,我们先来看看两者的关系:

首先,我们发现Thread是个类,而Runnable是接口,但凡计算机科班出身,或者参加过java面试的同学,都能轻而易举的说出类和接口的联系和区别,其中最重要的一点就是,类无法多重继承,而接口可以实现多个。好了,这就是Thread和Runnable的区别之一。

其次,我们发现Runnable接口方法中没有start()方法,而多线程激活需要这个方法,但这个方法存在于Thread类中。也就是可以说,对于实现Runnable接口的子类,也需要依靠Thread的start()方法来启动多线程。

最后,通过JDK文档,我们发现Thread类实现Runnable接口,即在本质上,Thread类是Runnable接口的子类。

 

了解了以上几点,相信大家都明白了Thread离不开Runnable,因为Runnable是他老子,而实现Runnable接口的子类也离不开Thread,因为要靠Thread来启动多线程,环环相扣,惺惺相惜,可昭日月~~

 

看完上面这段刻骨铭心的互相依赖关系,我们还是要写个观后感:建议读书者尽可能的使用Runnable接口去实现多线程机制,这样既可以避免了类的单继承局限,也可以使方法和启动解耦,而且也适合于资源共享!

 

等等,资源共享?上面没提到这个啊,这到底怎么回事?

对了,忘记说了,哈哈!我们还是来看代码吧,来个经典的12307-1关注的卖票问题,目前手头就五张票,要三个窗口一起卖,分别采用Thread和Runnable的方式:

public class SellTicket extends Thread {
	private int ticket = 5;//实际只有五张票
	@Override
	public void run() {
		// TODO Auto-generated method stub
		for(int i=0;i<100;i++){
			if(ticket>0){
				System.out.println(Thread.currentThread().getName()+" sell ticket["+ticket--+"]");
			}
		}
	}
	
	public static void main(String[] args) {
		//实例化了三个卖票对象,实际是各卖各的票,猜猜总共卖出去几张?
		new SellTicket().start();
		new SellTicket().start();
		new SellTicket().start();
	}
}

 

 

public class SellTicket implements Runnable {
	private int ticket = 5;//实际只有五张票
	@Override
	public void run() {
		// TODO Auto-generated method stub
		for(int i=0;i<100;i++){
			if(ticket>0){
				System.out.println(Thread.currentThread().getName()+" sell ticket["+ticket--+"]");
			}
		}
	}
	
	public static void main(String[] args) {
		//只实例化了一个卖票对象,实际是三个线程一起卖票,猜猜总共卖出去几张?
		SellTicket st = new SellTicket();
		new Thread(st).start();
		new Thread(st).start();
		new Thread(st).start();
	}
}

 

这就是Runnable的共享资源的好处,今天就到这,洗洗睡了~

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics