创建线程的几种代码方法

  1. 通过显示继承Thread类的方式来实现
    代码实现
package Java0509;

/**
 * @author wgsstart
 * @creat 2021-05-09 16:42
 */
public class ThreadDemo1 {//在这个代码中其实涉及到两个线程,MyThread创建出的线程,main方法对应的的主线程
    static class MyThread extends Thread {
        @Override
        public void run() {
            System.out.println("hello,world,我是一个线程");
        }
    }
    public static void main(String[] args) {
        /*
        * 创建线程需要使用Thread类,来创建一个Thread的实例,
        * 另一方面还需要给这个线程指定要执行哪些指令/代码,
        * 指定指令的方式有很多种,此处先用一种简单的,直接继承Thread类,重写Thread类中的run方法。*/
        Thread t = new MyThread();//[注意!]:当Thread对象被创建出来的时候,内核中并没有随之产生一个线程(PCB)
        t.start();//执行这个start方法,才是真的创建出了一个线程,此时内核中才随之出现了一个PCB,这个PCB就会对应让CPU来执行该线程的代码(上面的run方法中的逻辑)

    }

}

  1. 可以通过匿名内部类的方式继承Thread类
    代码实现
package Java0509;

/**
 * @author wgsstart
 * @creat 2021-05-09 17:43
 */
public class ThreadDemo2 {
    private static long count = 100_0000_0000L;//在一个较大的整数中适当的插入一些下划线,下划线不具备任何意义,但是能提高代码的可读性。
    public static void main(String[] args) {
       // serial();//串行,大概时间28秒
       concurrency();//并发,大概时间11秒

    }

    private static void concurrency() {
        long beg = System.currentTimeMillis();//时间戳

        Thread t1 = new Thread() {
      /*匿名内部类:创建了一个没有名字的类,只知道这个类继承自Thread。{}中是这个类的具体代码,同时也会new出来一个
      * 这个类的实例*/

            @Override
            public void run() {
                int a = 0;
                for (long i = 0; i < count; i++) {
                    a++;
                }
            }
        };
        Thread t2 = new Thread() {
            /*匿名内部类:创建了一个没有名字的类,只知道这个类继承自Thread。{}中是这个类的具体代码,同时也会new出来一个
             * 这个类的实例*/

            @Override
            public void run() {
                int b = 0;
                for (long i = 0; i < count; i++) {
                    b++;
                }
            }
        };
        t1.start();
        t2.start();
        try {
            t1.join();//线程等待,让主线程等待t1和t2执行结束,然后再继续往下执行。
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        /*t1,t2和main线程之间都是并发执行的,调用了t1.start 和 t2.start之后,两个新线程正在紧锣密鼓的进行计算过程中,
        * 此时主线程仍然会继续执行,下面的end就随之被计算了,正确的做法应该是要保证t1和t2都计算完毕,再来计算这个end的时间戳*/
        long end = System.currentTimeMillis();
        System.out.println("time: " + (end - beg) + "ms");

    }

    private static void serial() {//串行29秒
        long beg = System.currentTimeMillis();//时间戳
        int a = 0;
        for (long i = 0; i < count; i++) {
            a++;
        }
        int b = 0;
        for (long i = 0; i < count; i++) {
            b++;
        }
        long end = System.currentTimeMillis();
        System.out.println("time: " + (end - beg) + "ms");
    }
}

  1. 显示创建一个类,实现Runnable接口,然后把这个Runnable的实例关联到Thread实例上。
package Java0509;

import java.util.TimerTask;

/**
 * @author wgsstart
 * @creat 2021-05-09 20:16
 */
public class ThreadDemo3 {
    //Runnable本质上就是描述了一段要执行的任务代码是啥
    static class MyRunnable implements Runnable {
        @Override
        public void run() {
            System.out.println("我是一个新线程");
        }
    }
    public static void main(String[] args) {
        //3.显示创建一个类,实现Runnable接口,然后把这个Runnable的实例关联到Thread实例上。
       Thread t = new Thread(new MyRunnable());
       t.start();
    }
}

4.通过匿名内部类的方式来实现Runnable接口

package Java0509;

import java.util.TimerTask;

public class ThreadDemo3 {
    public static void main(String[] args) {
        //4.通过匿名内部类的方式来实现Runnable接口
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("我是一个新线程");
            }
        };
        Thread t = new Thread(runnable);
        t.start();
    }
}

5.使用lambda表达式来指定线程执行的内容

package Java0509;

import java.util.TimerTask;
public class ThreadDemo3 {
    public static void main(String[] args) {
        //5.使用lambda表达式来指定线程执行的内容
        Thread t = new Thread(() -> {
            System.out.println("我是一个新线程");
        });
        t.start();
    }
}

这五种创建线程的方式,没有本质上的区别(站在操作系统的角度),核心都是依靠Thread类,只不过指定线程执行的任务的方式有所差异。{
站在代码耦合性的角度,细节上有点区别,通过Runnable/lambda的方式来创建线程和继承Thread类相比,代码耦合性要小一些。在写Runnable或者lambda的时候,run中没有涉及到任何的Thread相关内容,这就意味着很容易把这个逻辑从多线程中剥离出来,去搭配其他的并发编程的方式来执行,当然也可以很容易改成不并发的方式来执行。
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值