和Runnable的区别以及如何关闭线程开启和关闭

Java并发编程(6):Runnable和Thread实现多线程的区别(含代码) - ImportNew
| 标签: ,
Java中实现多线程有两种方法:继承Thread类、实现Runnable接口,在程序开发中只要是多线程,肯定永远以实现Runnable接口为主,因为实现Runnable接口相比继承Thread类有如下优势:
1、可以避免由于Java的单继承特性而带来的局限;
2、增强程序的健壮性,代码能够被多个线程共享,代码与数据是独立的;
3、适合多个相同程序代码的线程区处理同一资源的情况。
下面以典型的买票程序(基本都是以这个为例子)为例,来说明二者的区别。
首先通过继承Thread类实现,代码如下:
class MyThread extends Thread{
private int ticket = 5;
public void run(){
for (int i=0;i&10;i++)
if(ticket & 0){
System.out.println(&ticket = & + ticket--);
public class ThreadDemo{
public static void main(String[] args){
new MyThread().start();
new MyThread().start();
new MyThread().start();
某次的执行结果如下:
从结果中可以看出,每个线程单独卖了5张票,即独立地完成了买票的任务,但实际应用中,比如火车站售票,需要多个线程去共同完成任务,在本例中,即多个线程共同买5张票。
下面是通过实现Runnable接口实现的多线程程序,代码如下:
class MyThread implements Runnable{
private int ticket = 5;
public void run(){
for (int i=0;i&10;i++)
if(ticket & 0){
System.out.println(&ticket = & + ticket--);
public class RunnableDemo{
public static void main(String[] args){
MyThread my = new MyThread();
new Thread(my).start();
new Thread(my).start();
new Thread(my).start();
某次的执行结果如下:
从结果中可以看出,三个线程一共卖了5张票,即它们共同完成了买票的任务,实现了资源的共享。
针对以上代码补充三点:
1、在第二种方法(Runnable)中,ticket输出的顺序并不是54321,这是因为线程执行的时机难以预测,ticket–并不是原子操作。
2、在第一种方法中,我们new了3个Thread对象,即三个线程分别执行三个对象中的代码,因此便是三个线程去独立地完成卖票的任务;而在第二种方法中,我们同样也new了3个Thread对象,但只有一个Runnable对象,3个Thread对象共享这个Runnable对象中的代码,因此,便会出现3个线程共同完成卖票任务的结果。如果我们new出3个Runnable对象,作为参数分别传入3个Thread对象中,那么3个线程便会独立执行各自Runnable对象中的代码,即3个线程各自卖5张票。
3、在第二种方法中,由于3个Thread对象共同执行一个Runnable对象中的代码,因此可能会造成线程的不安全,比如可能ticket会输出-1(如果我们System.out….语句前加上线程休眠操作,该情况将很有可能出现),这种情况的出现是由于,一个线程在判断ticket为1&0后,还没有来得及减1,另一个线程已经将ticket减1,变为了0,那么接下来之前的线程再将ticket减1,便得到了-1。这就需要加入同步操作(即互斥锁),确保同一时刻只有一个线程在执行每次for循环中的操作。而在第一种方法中,并不需要加入同步操作,因为每个线程执行自己Thread对象中的代码,不存在多个线程共同执行同一个方法的情况。
文章中是1.6和1.7, 可能版本有差异
关于ImportNew
ImportNew 专注于 Java 技术分享。于日 11:11正式上线。是的,这是一个很特别的时刻 :)
ImportNew 由两个 Java 关键字 import 和 new 组成,意指:Java 开发者学习新知识的网站。 import 可认为是学习和吸收, new 则可认为是新知识、新技术圈子和新朋友……
新浪微博:
推荐微信号
反馈建议:@
广告与商务合作QQ:
– 好的话题、有启发的回复、值得信赖的圈子
– 写了文章?看干货?去头条!
– 为IT单身男女服务的征婚传播平台
– 优秀的工具资源导航
– 活跃 & 专业的翻译小组
– 国内外的精选博客文章
– UI,网页,交互和用户体验
– JavaScript, HTML5, CSS
– 专注Android技术分享
– 专注iOS技术分享
– 专注Java技术分享
– 专注Python技术分享
& 2017 ImportNewjava线程Thread和Runnable的区别_百度知道
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。
java线程Thread和Runnable的区别
我有更好的答案
///question/610565.html?fr=iks&word=Runnable+hky_bd2010&ie=gbk" target="_blank">https:前者是类,后者是接口。底层的实现是一样(参考我之前的回答:<a href="https区别:///question/610565.html
采纳率:75%
为您推荐:
其他类似问题
&#xe675;换一换
回答问题,赢新手礼包&#xe6b9;博客分类:
我们都晓得java实现线程2种方式,一个是继承Thread,另一个是实现Runnable。
模拟窗口买票,第一例子继承thread,代码如下
public class ThreadTest {
public static void main(String[] args) {
Thread1 t1 = new Thread1("01");
Thread1 t2 = new Thread1("03");
t1.start();
t2.start();
//可以看出一共卖了200张票
class Thread1 extends Thread{
private int ticket = 100;
public Thread1(String name)
super(name);
public void run() {
while(ticket & 0)
System.out.println("窗口:"+Thread.currentThread().getName()+",卖了1个,剩余:"+(ticket--));
模拟窗口买票,实现Runnable接口,代码如下
public class RunnableTest {
public static void main(String[] args) {
Runnable1 r1 = new Runnable1();
new Thread(r1, "01").start();
new Thread(r1, "03").start();
//2个窗口一共卖了100张
class Runnable1 implements Runnable
private int ticket = 100;
public void run() {
while(ticket & 0)
System.out.println("窗口:"+Thread.currentThread().getName()+",卖了1个,剩余:"+(ticket--));
通过上面代码运行我们可以得到如下结论:
1.Thread和Runnable都可以实现多线程(废话)
2.Thread是类,而Runnable是接口,这就是类和接口区别,类只能继承一次,而接口可以实现多个接口。
3.Thread实现Runnable接口,这个可以查看Thread的源代码。
4.最重要的分享资源功能,一般我们使用多线程就是快速解决资源问题。Runnable可以实现资源分享,类实现Runnable并不具备线程功能,必须通过new Thread(runabble子类)调用start()启动线程,所以我们通常new一个runnable的子类,启动多个线程解决资源问题。Thread是类所以我们每次new一个对象时候资源已经实例化了,不能资源共享,Thread类要实现资源共享,可以声明变量为static,类共享的可以解决。
5.通过以上建议最好实现Runnable接口 实现多线程。
欢迎交流企鹅群:
30 顶17 踩
两个线程存在数据竞争,尽然不用锁?肯定要用,这只是写的测试案例而已
Thread t = new Thread1(); Thread t1 = new Thread(t,"01");& Thread t2 = new Thread(t,"03");& t1.start();& t2.start();& 这样写就能共享了,实际上和Runnable没什么区别。是的,可以的
浏览: 37068 次
来自: 南京
你这个根本就不对,我遍历了5遍,每次的到的count结果都不一 ...
spiniper 写道你这三段代码根本就没可比性。why?
你这三段代码根本就没可比性。
不错哦 给个赞
zx_code 写道郑州蘑菇云 写道为什么必须要加入呢?直接使 ...
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'博客分类:
Runnable比Thread要多一些优势,主要是以下两点
避免点继承的局限,一个类可以继承多个接口。
&!--?xml version="1.0" encoding="UTF-8" standalone="no"?--&
适合于资源的共享
第一点就不多说了,至于第二点看以下两个代码示例就清楚了
static class TicketThread extends Thread {
// 一共十张票
private int ticketNum = 10;
public void run() {
for (int i = 0; i & 20; i ++) {
if (this.ticketNum & 0) {
System.out.println("卖票 ticket:" + this.ticketNum --);
}}public static void main(String[] args) {
TicketThread thread1 = new TicketThread();
TicketThread thread2 = new TicketThread();
TicketThread thread3 = new TicketThread();
thread1.start();
thread2.start();
thread3.start();
以上是使用Thread方式写的,其实程序最后总共卖出了30张票,每个线程卖了10张。再看一下示例:
static class TicketThread implements Runnable {
// 一共十张票
private int ticketNum = 10;
public void run() {
for (int i = 0; i & 20; i ++) {
if (this.ticketNum & 0) {
System.out.println("卖票 ticket:" + this.ticketNum --);
}}public static void main(String[] args) {
TicketThread thread = new TicketThread();
new Thread(thread).start();
new Thread(thread).start();
new Thread(thread).start();
使用Runnable方式的话,由于三个线程共享了资源,所以最终也是卖出10张票,不会多,从而实现了资源共享。
博主不觉得你举的栗子会造成线程不安全吗?另外类前面加上static关键字,请问你是写的静态嵌套类?是静态嵌套类的确例子会造成线程不安全,多谢提醒。
浏览: 26420 次
来自: 北京
自己总结的?不错~
例子举得很好
描述的很详细,学习了
kk_liang 写道博主不觉得你举的栗子会造成线程不安全吗? ...
博主不觉得你举的栗子会造成线程不安全吗?另外类前面加上stat ...
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'博客分类:
两种定义方式
定义方式一:
class TestThread extends Thread{
public void run(){
........................
Thread t = new TestThread();
t.start();
定义方式二:
Thread t = new Runnable(
public void run(
..........
t.start();
JAVA基础(多线程Thread和Runnable的使用区别
Runnable是Thread的接口,在大多数情况下“推荐用接口的方式”生成线程,因为接口可以实现多继承,况且Runnable只有一个run方法,很适合继承。
在使用Thread的时候只需要new一个实例出来,调用start()方法即可以启动一个线程。
Thread Test = new Thread();
Test.start();
在使用Runnable的时候需要先new一个继承Runnable的实例,之后用子类Thread调用。
Test impelements Runnable
Test t = new Test();
Thread test = new Thread(t);
在某个题目里,需要分别打印出a与b各10次,并且每打印一次a睡1秒,打印一次b睡2秒。
可以在run方法外面定义String word与int time
Thread t1 = new Thread();
Thread t2 = new Thread();
t1.word = "a"
t1.time = 1000
t2.Word = "b"
t2.time = 2000
t1.start();
t2.start();
----Runnable的代码
class T implements Runnable{
String s = "";
int time = 0;
public void run (){
for (int i=0;i&10;i++) {
Thread.sleep(time);
} catch (InterruptedException e) {
Thread.interrupted();
System.out.println(s);
public class Test {
public static void main(String[] args) {
T t1 = new T();
T t2 = new T();
t1.s = "a";
t1.time = 100;
t2.s = "b";
t2.time = 200;
Thread a = new Thread(t1);
a.start();
Thread b = new Thread(t2);
b.start();
浏览: 1285612 次
来自: 珠海
很有用,谢谢
厉害,困扰了我很久
非常好,很实用啊。。
你好,你能把能讓這個程序的運行起來的代碼發我一下嗎?非常著急需 ...
可能配置有问题.
这文章我只是收藏转发而已, 并没有实 ...
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'}

我要回帖

更多关于 java 关闭线程 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信