线程创建与启动

文章详细介绍了Java中线程的创建,包括继承Thread类、实现Runnable接口和Callable接口,以及使用线程池的方式。此外,还讨论了线程的休眠方法Thread.sleep()和线程优先级的设置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、线程的创建

二、线程的实现方式 

1.方式一:继承java.lang.Thread类(线程子类)

2.方式二:实现  java.lang.Runnable 接口(线程执行类)

 3.实现  java.util.concurrent.Callable 接口,允许子线程返回结果、抛出异常

4.线程池

三、线程的休眠

四、线程的优先级

小结


一、线程的创建

        ● 通过创建Thread实例,完成线程的创建。
        ● 线程的内部实现可以通过继承Thread类、实现Runnable接口等方式进行封装。
        ● 通过调用Thread实例的start()方法启动新线程。

        通过Thread类创建子线程,然后调用start()方法启动子线程,由操作系统调度,程序本身无法确定线程的调度顺序,子线程与主线程同时运行,每次执行结果不同。

注:直接调用Thread实例的run()方法是无效的,因为直接调用相当于调用了普通的Java方法,不会有任何改变,必须重写run()方法

//每一个线程都是一个Thread对象
public class Demo1 {
    public static void main(String[] args) throws InterruptedException {
        System.out.println("主线程开始执行......");
        //创建子线程1
        Thread thread1 = new Thread("线程1"){
            @Override
            public void run() {
                for (int i = 0;i < 100;i ++){
                    System.out.println("子线程1:" + i);
                }
            }
        };
        //thread1.setPriority(10);        //设置线程优先级(1-10),默认是5
        thread1.start();                //启动线程1
        //创建线程2
        Thread thread2 = new Thread("线程2"){
            @Override
            public void run() {
                for (char c = 'A'; c < 'z'; c++) {
                    System.out.println("子线程2:" + c);
                }
            }
        };
        //thread2.setPriority(1);         //设置线程优先级(1-10),默认是5
        thread2.start();                //启动线程2

        System.out.println("主线程执行结束!!!!!");
    }
}

二、线程的实现方式 

1.方式一:继承java.lang.Thread类(线程子类)

        通过Thread类创建子线程,重写run()方法,在方法体中实现子线程。代码如下:

//线程创建方式1:继承Thread类
public class Demo2 {
    public static void main(String[] args) {
        SubThread t1 = new SubThread("线程1:");
        SubThread t2 = new SubThread("线程2:");
        SubThread t3 = new SubThread("线程3:");

        t1.start();
        t2.start();
        t3.start();
    }
}
//继承Thread,重写run()方法
class SubThread extends Thread{
    public SubThread(String name){
        super(name);
    }

    @Override
    public void run() {
        for (char c = 'A';c <='Z';c ++){
            System.out.printf("%s:%s\n",this.getName(),c);
        }
    }
}

2.方式二:实现  java.lang.Runnable 接口(线程执行类)

        以邮件任务为例,编写子类实现Runnable接口,重写run()方法,完成子进程的实现。

//线程创建方式2:实现Runnable接口
public class Demo3 {
    public static void main(String[] args) {
        //每个Runnable接口的实现类,封装了线程执行逻辑
        EmailTask emailTask = new EmailTask();

        //创建3个线程,分别发送邮件
        Thread t1 = new Thread(emailTask,"线程1:");
        Thread t2 = new Thread(emailTask,"线程2:");
        Thread t3 = new Thread(emailTask,"线程3:");

        //启动线程
        t1.start();
        t2.start();
        t3.start();
    }
}
//子类(邮件任务)
class EmailTask implements Runnable{
    public void run(){
        //获取当前线程对象
        Thread currentThread = Thread.currentThread();

        //获取线程名称
        String name = currentThread.getName();
        System.out.println(name + "使用JavaMail技术,通过smtp协议发送邮件");
    }

}

 3.实现  java.util.concurrent.Callable 接口,允许子线程返回结果、抛出异常

        创建任务类继承Callable()接口,重写call()方法,创建子线程,将子线程封装为FutureTask对象,然后启动。

//线程创建方式3:实现Callable接口
//用三个线程计算1-1000的累计和
public class Demo4 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //Callable接口实现类:不同数据范围的计算任务
        SunCalcTask task1 = new SunCalcTask(1,300);
        SunCalcTask task2 = new SunCalcTask(301,600);
        SunCalcTask task3 = new SunCalcTask(601,1000);

        //Callable-->FutureTask(Runnable接口实现类)
        FutureTask<Integer> fTask1 = new FutureTask<Integer>(task1);
        FutureTask<Integer> fTask2 = new FutureTask<Integer>(task2);
        FutureTask<Integer> fTask3 = new FutureTask<Integer>(task3);

        //创建并启动线程
        Thread thread1 = new Thread(fTask1);
        Thread thread2 = new Thread(fTask2);
        Thread thread3 = new Thread(fTask3);

        //线程启动
        //futureTask.run()-->callable.call()-->outcome结果
        thread1.start();
        thread2.start();
        thread3.start();

        //线程执行结束,分别湖区各自线程的返回结果
        System.out.println("开始分别获取:");
        Integer sum1 = fTask1.get();
        Integer sum2 = fTask2.get();
        Integer sum3 = fTask3.get();
        //最终计算结果
        Integer result = sum1 + sum2 + sum3;
        System.out.println(result);

    }
}
//通过Callable接口实现类SumCalcTask封装某个范围内的累加和
class SunCalcTask implements Callable<Integer>{
    public SunCalcTask(Integer begin,Integer end){
        this.begin = begin;
        this.end = end;
    }
    private int begin,end;
    @Override
    public Integer call() throws Exception {
        int total = 0;
        for (int i = begin;i <= end;i++){
            total += i;
        }
        System.out.println(Thread.currentThread().getName() + "线程执行了1次");
        return total;
    }
}

4.线程池

        线程池,按照配置参数(核心线程数、最大线程数等)创建并管理若干线程对象。程序中如果需要使用线程,将一个执行任务传给线程池,线程池就会使用一个空闲状态的线程来执行这个任务。执行结束以后,该线程并不会死亡,而是再次返回线程池中成为空闲状态,等待执行下一个任务。

//线程的创建方式4:通过线程池创建
public class Demo5 {
    public static void main(String[] args) {
        //固定数量10的线程池
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        //不确定数量的线程请求
        while (true) {
            //向线程池提交一个执行任务(Runnable接口实现类对象)
            //线程池分配一个”空闲线程“执行该任务
            //如果没有空闲线程,则该任务进入”等待队列(工作队列)"
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName() + "执行了一次");
                    try {
                        Thread.sleep(1000);     //当前线程休眠1000毫秒
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            });
        }
    }
}

三、线程的休眠

        可以通过调用Thread.sleep(long millis),强迫当前线程按照指定毫秒值休眠(休眠结束后自动唤醒),使用该方法可以人为控制某个线程优先执行。

Thread.sleep(1000)     //控制线程休眠1000毫秒

四、线程的优先级

        通过setPriority(int n)设置线程优先级,范围是1-10,默认为 5 ,优先级高的线程被操作系统调度的优先级较高(操作系统对高优先级线程,调度更频繁),但并不能保证优先级高的一定先执行

        thread1.setPriority(8); // 设置数字线程优先级=8
        thread2.setPriority(1); // 设置字母线程优先级=1

小结

● Java用Thread对象表示一个线程,通过调用start()启动一个新线程;
● 一个线程对象只能调用一次start()方法;
● 线程的执行代码写在run()方法中;
● 线程调度由操作系统决定,程序本身无法决定调度顺序;
● Thread.sleep()可以把当前线程暂停一段时间,(时间结束后自动唤醒)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sorenw

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值