您的位置:首页 > 编程语言 > Java开发

Java 多线程 -Thread 和Runnable 的区别和联系

2017-05-29 16:25 363 查看
最近面试美团,问到了这两个的区别

在Java中实现多线程无非就是两个形式

(1)继承Thread类

(2)实现Runnable的接口;

如果研究一下源码就会发现:Thread其实本身就是实现了接口Runnable的一个类;

因此Thread中的方法和成员变量要比Runnable多,最典型地就是Thread有start()方法,但是Runnable接口没有start()方法;

如果想要执行一段线程:


publicthreadTestextendsThread{...

@Override
publicvoidrun(){..}

}

threadTestth1=newthreadTest("一号窗口");

th1.start();



这里继承了Thread类,并且重写了方法run();

然后调用此类的start()方法来执行,记住不是调用run()方法执行,而是start(),因为:

 1.run()并不是启动线程,而是简单的方法调用。

 2.并不是一启动线程(调用start()方法)就执行这个线程,而是进入就绪状态,什么时候运行要看CUP。

Runnable和Thread区别

实际开发中我们通常采用Runnable接口来实现多线程。因为实现Runnable接口比继承Thread类有如下好处:
1.避免继承的局限,一个类可以继承多个接口,但是类只能继承一个类。
2.Runnable接口实现的线程便于资源共享。而通过Thread类实现,各自线程的资源是独立的,不方便共享。

参考:http://blog.csdn.net/uudou/article/details/51841781

Runnable接口和Thread之间的联系:

publicclassThreadextendsObjectimplementsRunnable

发现Thread类也是Runnable接口的子类。

针对于区别的第二条:Runnable接口实现的线程便于资源共享,而通过Thread类实现,各自的线程的资源是独立的,不方便共享。

举个栗子:

网上最经典的卖票的例子:

(1)继承Thread类:

packagecom.thread;
/*
*通过继承Thread类,实现多线程
*Thread类是有run()方法的;
*也有start方法

**/

publicclassthreadTestextendsThread{

privateintticket=10;

privateStringname;

publicthreadTest(Stringname){
this.name=name;
}

@Override
publicvoidrun(){
//TODOAuto-generatedmethodstub
//super.run();
while(true){
if(this.ticket>0){
try{
Thread.sleep(1000);
}catch(InterruptedExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
System.out.println(this.name+"卖票--->"+(this.ticket--));
}else{
break;
}
}
}

publicstaticvoidmain(String[]args){
//TODOAuto-generatedmethodstub
threadTestth1=newthreadTest("一号窗口");
threadTestth2=newthreadTest("二号窗口");
th1.start();
th2.start();
//threadTestmt=newthreadTest();
//Threadt1=newThread(mt,"一号窗口");
//Threadt2=newThread(mt,"二号窗口");
//t1.start();
//t2.start();

}

}


执行的结果为:

一号窗口卖票--->10
二号窗口卖票--->10
一号窗口卖票--->9
二号窗口卖票--->9
一号窗口卖票--->8
二号窗口卖票--->8
二号窗口卖票--->7
一号窗口卖票--->7
二号窗口卖票--->6
一号窗口卖票--->6
二号窗口卖票--->5
一号窗口卖票--->5
二号窗口卖票--->4
一号窗口卖票--->4
一号窗口卖票--->3
二号窗口卖票--->3
一号窗口卖票--->2
二号窗口卖票--->2
一号窗口卖票--->1
二号窗口卖票--->1


(2)实现Runnable接口:

packagecom.thread;
/*
*通过实现Runnable接口,实现多线程
*Runnable类是有run()方法的;
*但是没有start方法
**/

publicclassrunnableTestimplementsRunnable{

privateintticket=10;

//publicStringname;
//
//publicrunnableTest(StringtName){
//this.name=tName;
//}

@Override
publicvoidrun(){
//TODOAuto-generatedmethodstub
//super.run();
while(true){
if(ticket>0){
try{
Thread.sleep(1000);
}catch(InterruptedExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"卖票--->"+(this.ticket--));
}else{
break;
}
}
}

publicstaticvoidmain(String[]args){
//TODOAuto-generatedmethodstub
//runnableTestth1=newrunnableTest("一号窗口");
//runnableTestth2=newrunnableTest("二号窗口");
//newThread(th1).start();
//newThread(th2).start();

runnableTestmt=newrunnableTest();
Threadt1=newThread(mt,"一号窗口");
Threadt2=newThread(mt,"二号窗口");
t1.start();
t2.start();

}

}


执行结果为:

一号窗口卖票--->10
二号窗口卖票--->9
一号窗口卖票--->8
二号窗口卖票--->7
一号窗口卖票--->6
二号窗口卖票--->5
一号窗口卖票--->4
二号窗口卖票--->3
一号窗口卖票--->2
二号窗口卖票--->1
一号窗口卖票--->0


可以看到:Thread各线程资源是独立的,Runnable便于实现线程共享资源;

参考:
http://mars914.iteye.com/blog/1508429http://www.oschina.net/question/565065_86563
http://blog.csdn.net/uudou/article/details/51841781
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: