Runnable和Thread的区别

前言

      Runnable和Thread广泛用于多线程的开发,关于Runnable和Thread的区别,在网上搜了很多帖子或文章,感觉解释得都不甚明了,这里从使用的角度分析一下两者的区别。

正文

1、Runnable例子-不能并发

package com.hf.test.jar;

public class RunnableTest {

    /**
     * 定义runnable实现类
     * @author hf
     *
     */
    public class MyRunnable implements Runnable{
        String objectid = null;
        
        public MyRunnable(String objid){
            objectid = objid;
        }
        
        public void run(){
            int i =0;
            while(i<100){
                System.out.println(objectid + "-" + Thread.currentThread().getId() + "-A" + i);
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                
                i++;
            }
        }
    };
    
    
    /**
     * 测试多个Runnable
     */
    public void test1(){
        for(int i=0;i<3;i++){
            new MyRunnable("instance" + i).run();
        } 
    }
    
    
    public static void main(String[] args) {
        RunnableTest rt = new RunnableTest();
        rt.test1();
    }
}

结果(部分):

instance0-1-A87
instance0-1-A88
instance0-1-A89
instance0-1-A90
instance0-1-A91
instance0-1-A92
instance0-1-A93
instance0-1-A94
instance0-1-A95
instance0-1-A96
instance0-1-A97
instance0-1-A98
instance0-1-A99
instance1-1-A0
instance1-1-A1
instance1-1-A2
instance1-1-A3
instance1-1-A4
instance1-1-A5

可以看到3个Runnable按顺序执行,并未能并发执行。一个Runnable执行完了,再执行下一个Runnable。

使用JVisualVM监控工具监控到的结果显示,并未开启新的进程,仍然在主线程上执行。

2、Thread例子-不能并发

package com.hf.test.jar;


public class ThreadTest1 {
    
    public class MyThread extends Thread{
        String objectid = null;
        
        public MyThread(String objid){
            objectid = objid;
        }
        
        public void run(){
            int i =0;
            while(i<100){
                System.out.println(objectid + "-" + Thread.currentThread().getId() + "-A" + i);
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                
                i++;
            }
        }
    };
    

    public void test1(){ 
        for(int i=0;i<3;i++){
            new MyThread("instance" + i).run();
        } 
    }
    
    
    public static void main(String[] args) {
        ThreadTest1 rt = new ThreadTest1();
        rt.test1();
    }
}

结果(部分):

instance0-1-A92
instance0-1-A93
instance0-1-A94
instance0-1-A95
instance0-1-A96
instance0-1-A97
instance0-1-A98
instance0-1-A99
instance1-1-A0
instance1-1-A1
instance1-1-A2
instance1-1-A3
instance1-1-A4
instance1-1-A5
instance1-1-A6
instance1-1-A7

可以看到,Thread方式并未以并发的方式运行,仍然和例1一样是顺序执行。

3、例子3-Thread-start启动-可以并发

我们将Thread的执行方法由run()改为start(),然后再做测试。

代码:

package com.hf.test.jar;


public class ThreadTest1b {
    
    public class MyThread extends Thread{
        String objectid = null;
        
        public MyThread(String objid){
            objectid = objid;
        }
        
        public void run(){
            int i =0;
            while(i<100){
                System.out.println(objectid + "-" + Thread.currentThread().getId() + "-A" + i);
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                
                i++;
            }
        }
    };
    

    public void test1(){ 
        for(int i=0;i<3;i++){
            new MyThread("instance" + i).start();
        } 
    }
    
    
    public static void main(String[] args) {
        ThreadTest1b rt = new ThreadTest1b();
        rt.test1();
    }
}

结果(部分):

instance0-10-A0
instance2-12-A0
instance1-11-A0
instance1-11-A1
instance2-12-A1
instance0-10-A1
instance1-11-A2
instance0-10-A2
instance2-12-A2
instance1-11-A3
instance0-10-A3
instance2-12-A3
instance1-11-A4

可见,Thread以并发的方式运行,3个线程交替执行。通过JVisiualVM监控工具,发现确实多了3个线程:

那么实现Runnable的类可不可以并发执行呢?

4、Runnable-可以并发

将Runnable类用Thread包裹,并使用Thread的start()方法,则可以实现Runnable类并发执行。

代码:

package com.hf.test.jar;

import java.io.Serializable;

public class RunnableTest3 {

    /**
     * 定义runnable实现类
     * @author hf
     *
     */
    public class MyRunnable implements Runnable{
        String objectid = null;
        
        public MyRunnable(String objid){
            objectid = objid;
        }
        
        public void run(){
            int i =0;
            while(i<100){
                System.out.println(objectid + "-" + Thread.currentThread().getId() + "-A" + i);
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                
                i++;
            }
        }
    };
    
    
    /**
     * 测试多个Runnable
     */
    public void test1(){
        for(int i=0;i<3;i++){
            new Thread(new MyRunnable("instance" + i)).start();
        } 
    }
    
    
    public static void main(String[] args) {
        RunnableTest3 rt = new RunnableTest3();
        rt.test1();
    }
}

结果(部分):

instance0-10-A0
instance2-12-A0
instance1-11-A0
instance0-10-A1
instance1-11-A1
instance2-12-A1
instance2-12-A2
instance1-11-A2
instance0-10-A2
instance2-12-A3
instance1-11-A3
instance0-10-A3
instance2-12-A4
instance0-10-A4

总结:

1、Runnable和Thread类均可以实现并发执行,但Runnable并发执行时需要依赖于Thread。

2、要实现并发执行,要执行Thread类的start()方法,而不是run()方法。

3、Runnable在实现多继承上有优势,而Thread则无法再使用implement实现多继承。

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值