创建线程的三种方法

一、三种方法的编程实现

1.Thread

public class Thread创建线程 {

    /**
     * 
    * <p>Description: 非静态内部类中默认持有外部类的引用.
    * 优点:编程简单,无需通过Thread.currentThread()获取当前线程,通过this即可获取
    * 缺点:不能再继承其他类</p>  
    * @author 杨丽金  
    * @date 2018-4-16  
    * @version 1.0
     */
    static class MyThread extends Thread{
        
        public void run(){
            for(int i=0;i<100;i++){
                System.out.println(this.getName()+":"+i);
            }
        }
    }
    
    public static void main(String[] args) {
        for(int i=0;i<100;i++){
            if(i==20){
                new MyThread().start();
            }
            System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }
}

2.Runnable

public class Runnable创建线程 {

    /**
     * 
    * <p>Description: Runnable创建线程
    * 优点:1)可以继承别的类
    *       2)多个线程可以共享target对象,非常适合多个线程共享同一份资源的情况
    * 缺点:获取当前要线程要通过Thread.currentThread()方法
    * </p>  
    * @author 杨丽金  
    * @date 2018-4-16  
    * @version 1.0
     */
    static class MyRunnable implements Runnable{
        // 变量会被创建的多个线程共享,存在线程同步问题
        volatile int  i=0;
        public void run(){
            // 方法中的局部变量是线程私有的,是线程安全的 
            for(;i<100;i++){
                System.out.println(Thread.currentThread().getName()+":"+i);
            }
        }
    }
    
    public static void main(String[] args) {
        /*for(int i=0;i<100;i++){
            if(i==20){
                new Thread(new MyRunnable()).start();
            }
            System.out.println(Thread.currentThread().getName()+":"+i);
        }*/
        // 演示两个子线程线程共享变量的例子
        Runnable r=new MyRunnable();
        new Thread(r,"子线程1").start();
        new Thread(r,"子线程2").start();
    }
}

3.Callable

/**
 * 
* <p>Description: 
* 优点:1)可以继承别的类
*       2)多个线程可以共享target对象,非常适合多个线程共享同一份资源的情况
* 缺点:获取当前要线程要通过Thread.currentThread()方法</p>  
* @author 杨丽金  
* @date 2018-4-16  
* @version 1.0
 */
public class Callable创建线程 {
    public static void main(String[] args) {
        
        for(int i=0;i<100;i++){
            System.out.println(Thread.currentThread().getName()+":"+i);
            if(i==20){
                // 开启线程
                /*
                 * Callable接口不是Runnable接口的子接口,故不可作为Thread的target传入
                 * Callable是泛型接口,使用时需要指定泛型
                 */
                Callable<Integer> ca=new MyCallable();
                /*
                 * 此处是泛型的菱形语法
                 * Future接口,JAVA提供了它的一个实现类FutureTask(实现了Future接口和Runnable接口),可以作为Thread的target传入
                 */
                FutureTask<Integer> ft=new FutureTask<>(ca);
                Thread t=new Thread(ft);
                t.start();
                try {
                    /*
                     * 调用get()方法后主线程会被阻塞,等待子线程返回结果
                     */
                    System.out.println("线程返回结果"+ft.get());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }
            }
        }
        
    }
    
    static class MyCallable implements Callable<Integer>{
        // 该变量可被多个线程共享
        int i=0;
        /**
         * call()方法是线程执行体
         * 1)可以有返回值,泛型指定
         * 2)可以声明抛出的异常
         */
        @Override
        public Integer call() throws Exception {
            for(i=0;i<100;i++){
                System.out.println(Thread.currentThread().getName()+":"+i);
            }
            return i;
        }
        
    }

}

二、方法的优缺点对比

  1. 通过继承Thread类创建线程:
  • 优:编程简单。可通过this关键字直接获得当前线程
  • 缺:单继承多接口
  1. 通过实现接口创建线程:
  • 优:1)适合多个线程共享同一份资源的情况;2)单继承多接口
  • 缺:编程复杂。需要通过Thread.currentThread()获取当前线程

通过实现Callable接口(这是一个泛型接口,在其实现类中要指定具体的泛型类型):1)线程执行体可指定返回值,2)并且可声明异常【可不声明】
通过实现Runnable接口:无上述特性

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,692评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,482评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,995评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,223评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,245评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,208评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,091评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,929评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,346评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,570评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,739评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,437评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,037评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,677评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,833评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,760评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,647评论 2 354

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,652评论 18 139
  • 一.线程与进程相关 1.进程   定义:进程是具有独立功能的程序关于某个数据集合上的一次运行活动,进程是操作系统分...
    Geeks_Liu阅读 1,713评论 2 4
  • 记忆里的味道,是很难在往后的日子里重遇的。 今晚不知怎么的,记忆又将我拉回到那个时候,往日的场景又...
    闲度夕人阅读 229评论 0 3
  • 现在回想,终于明白老玩家说的水位和盘口的道理了,看初赔的也是很有道理的。看盘口水位的实际上是看庄家规避风险所反应的...
    猪猪9527阅读 262评论 0 0
  • 书籍《解忧杂货店》,以奇幻、治愈与救赎著称,豆瓣评分8.6,连续四年上榜亚马逊最畅销图书,当之无愧的大IP。 一番...
    游侠与夜莺阅读 495评论 0 0