Java 多线程(二)线程的创建方式

线程的创建方式?

线程的创建方式有四种。

  • 一、继承 Thread 类创建线程类;
  • 二、通过 Runnable 接口创建线程;
  • 三、使用匿名内部类的方式;
  • 四、通过 Callable 接口和 FutureTask 类来创建线程。

Thread 类

  • 定义 Thread 类的子类,并重写该类的 run() 方法,该 run() 方法的方法体就是该线程需要完成的任务。因此把 run() 方法称为执行体。
  • 创建 Thread 子类的实例,就是创建了线程对象。
  • 调用线程对象的 start() 方法来启动线程。
/**
 * @Author : PengPeng
 * 第一种创建线程的方式 继承 Thread 类
 */
public class ThreadDemo01 {
    public static void main(String[] args) {
        System.out.println("====程序开始====");
        ThreadDemo001 t1 = new ThreadDemo001();
        // start() 方法启动线程
        t1.start();
        System.out.println("主线程开始");
        for (int i = 0; i < 10; i ++){
            System.out.println(Thread.currentThread().getName() + ":" + i);
        }
        System.out.println("主线程结束");
    }
}

class ThreadDemo001 extends Thread{
    /**
     * run 方法里面写需要执行的代码
     */
    @Override
    public void run() {
        System.out.println("子线程开始");
        for(int i = 0; i < 10; i ++){
            System.out.println(Thread.currentThread().getName() + ":" + i);
        }
        System.out.println("子线程结束");
    }
}
  • 执行结果
====程序开始====
主线程开始
main:0
main:1
main:2
main:3
子线程开始
main:4
main:5
main:6
Thread-0:0
main:7
main:8
main:9
主线程结束
Thread-0:1
Thread-0:2
Thread-0:3
Thread-0:4
Thread-0:5
Thread-0:6
Thread-0:7
Thread-0:8
Thread-0:9
子线程结束

Process finished with exit code 0

Runnable 接口

  • 定义 Runnable 接口的实现类,并重写该接口的 run() 方法,该 run() 方法的方法体同样是该线程的线程执行体。
  • 创建 Runnable 实现类的实例,并以此实例作为 Thread 类的构造函数的参数来创建 Thread 对象,该 Thread 对象才是真正的线程对象。
  • 调用该线程对象的 start() 方法来启动该线程。
/**
 * @Author : PengPeng
 * 第二种创建线程的方式 实现 Runnable 接口,再放入 Thread
 */
public class ThreadDemo02 {
    public static void main(String[] args) {
        System.out.println("====程序开始====");
        ThreadDemo002 t2 = new ThreadDemo002();
        Thread thread = new Thread(t2);
        thread.start();
        System.out.println("主线程开始");
        for (int i = 0; i < 10; i ++){
            System.out.println(Thread.currentThread().getName() + " : " + i);
        }
        System.out.println("主线程结束");
    }
}

class ThreadDemo002 implements Runnable{
    @Override
    public void run() {
        System.out.println("子线程开始");
        for (int i = 0; i < 10; i ++){
            System.out.println(Thread.currentThread().getName() + " : " + i);
        }
        System.out.println("子线程结束");
    }
}
  • 执行结果
====程序开始====
主线程开始
main : 0
main : 1
子线程开始
main : 2
main : 3
main : 4
main : 5
main : 6
main : 7
Thread-0 : 0
main : 8
Thread-0 : 1
main : 9
主线程结束
Thread-0 : 2
Thread-0 : 3
Thread-0 : 4
Thread-0 : 5
Thread-0 : 6
Thread-0 : 7
Thread-0 : 8
Thread-0 : 9
子线程结束

Process finished with exit code 0

匿名内部类

/**
 * @Author : PengPeng
 * 第三种创建线程的方式 匿名内部类
 */
public class ThreadDemo03 {
    public static void main(String[] args) {
        System.out.println("====程序开始====");
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("子线程开始");
                for (int i = 0; i < 10; i++) {
                    System.out.println(Thread.currentThread().getName() + ": " + i);
                }
                System.out.println("子线程结束");
            }
        }).start();

        System.out.println("主线程开始");
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName() + ": " + i);
        }
        System.out.println("主线程结束");
    }
}
  • 执行结果
====程序开始====
主线程开始
main: 0
main: 1
main: 2
main: 3
main: 4
main: 5
子线程开始
main: 6
Thread-0: 0
Thread-0: 1
Thread-0: 2
Thread-0: 3
main: 7
main: 8
main: 9
主线程结束
Thread-0: 4
Thread-0: 5
Thread-0: 6
Thread-0: 7
Thread-0: 8
Thread-0: 9
子线程结束

Process finished with exit code 0

Callable 接口和 FutureTask 类

  • 创建 Callable 接口的实现类,并实现 call() 方法,该 call() 方法将作为线程执行体,并且有返回值。
  • 创建 Callable 实现类的实例,并以此实例作为 FutureTask 类的构造函数的参数来创建 FutureTask 对象,该封装了该 Callable 对象的 call() 方法的返回值。
  • 使用 FutureTask 对象作为 Thread 类的构造函数的参数来创建 Thread 线程对象,并调用 start() 方法来启动该线程。
  • 调用 FutureTask 对象的 get() 方法来获得子线程执行结束后的返回值。
/**
 * @Author : PengPeng
 * 第四种创建线程的方式 Callable 接口和 FutureTask 类
 */
public class ThreadDemo04 {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        System.out.println("====程序开始====");
        ThreadDemo004 t4 = new ThreadDemo004();
        FutureTask futureTask = new FutureTask(t4);
        Thread thread = new Thread(futureTask);
        thread.start();
        System.out.println("主线程开始");
        for (int i = 0; i < 10; i ++){
            System.out.println(Thread.currentThread().getName() + " :" + i);
        }
        System.out.println("主线程结束");
        // 执行完再拿返回值,不然卡死;
        System.out.println("子线程计算出的值为:" + futureTask.get());
    }

}

class ThreadDemo004 implements Callable {

    @Override
    public Object call() throws Exception {
        System.out.println("子线程开始");
        int temp = 0;
        for (int i = 1; i <= 10; i++) {
            System.out.println(Thread.currentThread().getName() + " : " + i);
            temp += i;
        }

        System.out.println("子线程结束");
        return temp;
    }
}
  • 执行结果
====程序开始====
主线程开始
main :0
main :1
main :2
子线程开始
main :3
Thread-0 : 1
main :4
main :5
Thread-0 : 2
main :6
main :7
main :8
main :9
主线程结束
Thread-0 : 3
Thread-0 : 4
Thread-0 : 5
Thread-0 : 6
Thread-0 : 7
Thread-0 : 8
Thread-0 : 9
Thread-0 : 10
子线程结束
子线程计算出的值为:55

Process finished with exit code 0

常用 API

常用线程 API 方法常用线程构造函数
start() 启动线程Thread() 分配一个新的 Thread 对象
currentThread() 获取当前线程对象Thread(String name) 分配一个新的 Thread对象,具有指定的 name 正如其名
getID() 获取当前线程 IDThread(Runnable r) 分配一个新的 Thread 对象
getName() 获取当前线程名称Thread(Runnable r, String name) 分配一个新的 Thread 对象
sleep() 休眠线程
stop() 停止线程

总结:

  • 使用继承 Thread 类的方法好,还是使用实现 Runnable 接口的方法好?

使用实现 Runnable 接口的方法好!因为实现了接口还可以继续继承,继承了 Thread 类就不能在继承其它类了。

  • 启动线程是调用 start() 方法还是 run() 方法?

启动线程的方法是 start() 方法

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值