java 多线程 多线程概述及其三种创建方式 线程的常用方法

本文详细介绍了Java中多线程的三种创建方式:继承Thread类、实现Runnable接口和使用Callable/FutureTask。包括线程的启动、Callable的call方法、FutureTask的应用以及线程的常见方法如getName(),run(),join(),sleep()的使用示例。
摘要由CSDN通过智能技术生成

多线程概述及其三种创建方式

请添加图片描述

请添加图片描述







创建方式一 继承Thread类

请添加图片描述

请添加图片描述

代码演示一下线程的创建和使用:
请添加图片描述

图中主线程和t线程一起在跑,每次运行程序可以发现主线程和t线程之间输出的交叉顺序是随机的,说明是多线程运行。

请添加图片描述






创建方式二 实现Runnable接口

请添加图片描述

请添加图片描述

请添加图片描述

请添加图片描述

请添加图片描述





创建方式三 利用Callable接口、FutureTask类来实现

请添加图片描述

请添加图片描述

请添加图片描述

/**
 * 1、让这个类实现Callable接口
 */
public class MyCalllable implements Callable<String> {
    public MyCalllable(int n) {
        this.n = n;
    }
    private int n;

    // 2、重写call方法
    @Override
    public String call() throws Exception {
        //描述线程的任务,返回线程执行后的结果
        //需求:求1-n的和返回
        int sum=0;
        for (int i = 1; i <= n; i++) {
            sum+=i;
        }
        return "线程求出了1-"+ n + "的和是:" + sum;
    }
}
/**
 * 目标:掌握线程的创建方式三:实现Callable接口
 */
public class main {
    public static void main(String[] args) throws Exception {
        //3、创建一个Callable的对象
        Callable<String> call = new MyCalllable(100);

        //4、把Callable对象封装成一个FutureTask对象(任务对象)
        //未来对象的作用?
        //(1) 是一个任务对象,实现了Runnable接口
        //(2) 可以在线程执行完毕之后,用未来任务对象调用get方法获取线程执行完毕之后的返回值
        FutureTask<String> f1 = new FutureTask<>(call);

        //5、把任务对象交给一个Thread对象
        new Thread(f1).start();

        //6、获取线程执行完毕之后返回的结果
        //注意:如果主线程执行到这,假如上面的线程还没有执行完毕
        //则这里的代码会暂停,等待上面的线程执行完毕之后返回结果
        String rs = f1.get();
        System.out.println(rs);
    }
}



线程的常用方法

请添加图片描述

下面我们演示一下这些方法的使用效果。

public class MyThread extends Thread{
    public MyThread() {

    }
    public MyThread(String name){
        super(name); //1.执行父类Thread(String name)构造器,为当前线程设置名字了
        //相当于在main里执行t3.setName("3号线程") 设置线程名称;
    }
    @Override
    public void run() {
        //2.currentThread() 哪个线程执行它,它就会得到哪个线程对象。
        Thread t = Thread.currentThread();
        for (int i = 1; i <= 3; i++) {
            //3.getName() 获取线程名称
            System.out.println(t.getName() + "输出:" + i);
        }
    }
}
public static void main(String[] args) throws Exception {
        Thread t1 = new MyThread();
        t1.start();
        System.out.println(t1.getName());//Thread-0(默认线程名,如果下面t2不设置名字将是Thread-1)

        Thread t2 = new MyThread("2号线程");
        t2.start();
        System.out.println(t2.getName()); // 2号线程

        Thread t3 = new MyThread();
        t3.setName("3号线程");
        t3.start();
        System.out.println(t3.getName()); // 3号线程

        // 输出主线程对象的名字
        // 哪个线程执行下面的函数,它就会得到哪个线程对象。
        Thread m = Thread.currentThread();
        System.out.println(m.getName()); // main
        m.setName("最牛的线程");
        System.out.println(m.getName()); // 最牛的线程

        for (int i = 1; i <= 5; i++) {
            System.out.println(m.getName() + "线程输出:" + i);
        }
    }

main的执行结果为:

Thread-0
2号线程
3号线程
main
最牛的线程
最牛的线程线程输出:1
Thread-0输出:1
2号线程输出:1
3号线程输出:1
2号线程输出:2
Thread-0输出:2
最牛的线程线程输出:2
Thread-0输出:3
2号线程输出:3
3号线程输出:2
最牛的线程线程输出:3
3号线程输出:3
最牛的线程线程输出:4
最牛的线程线程输出:5

最后再演示一下join这个方法是什么效果。

public class ThreadTest2 {
    public static void main(String[] args) throws Exception {
        // join方法作用:让当前调用这个方法的线程先执行完。
        Thread t1 = new MyThread("1号线程");
        t1.start();
        t1.join();

        Thread t2 = new MyThread("2号线程");
        t2.start();
        t2.join();

        Thread t3 = new MyThread("3号线程");
        t3.start();
        t3.join();
    }
}

执行效果是1号线程先执行完,再执行2号线程;2号线程执行完,再执行3号线程。

还有sleep方法:

请添加图片描述

请添加图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值