多线程--02--线程四种创建方式

package com.fuping3.basic;

/**
 * 实现多线程方式一
 * 优点:编写简单,可直接用this.getname()获取当前线程,不必使用Thread.currentThread()方法。
 * 缺点:
 *     1、使用继承方式,MyThread不能再继承其他类
 *     2、无返回值
 */
public class MyThread extends Thread{
    @Override
    public void run() {
        while(true){
            try {
                Thread.sleep(1000);
                System.out.println("Thread--当前运行线程:"+Thread.currentThread().getName());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }

    public static void main(String[] args) {
        //创建Thread类的子类的对象
        MyThread t=new MyThread();

        /**
         * 通过此对象调用start():①启动当前线程 ② 调用当前线程的run()
         *
         * 注意点一:我们不能通过直接调用run()的方式启动线程。
         *        t.run();
         */
        t.start();

        /**
         * 注意点二:再启动一个线程,不可以还让已经start()的线程去执行,否则抛异常IllegalThreadStateException
         *        t.start();
         *        解决:我们需要重新创建一个线程的对象
         */
        MyThread t2=new MyThread();
        t2.start();
    }
}

二、实现Runnable接口

package com.fuping3.basic;
/**
 * 实现多线程方式二--推荐
 * 优点:避免了单继承的局限性、多个线程可以共享一个Runnable对象
 * 缺点:
 *      1、无返回值
 *      2、访问线程必须使用Thread.currentThread()方法
 */
public class MyRunnable implements Runnable{
    public void run() {
        while(true){
            try {
                Thread.sleep(1000);
                System.out.println("Runnable--当前运行线程:"+Thread.currentThread().getName());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        //创建实例对象
        MyRunnable runnable=new MyRunnable();
        //须将Runnable对象作为参数传递到Thread类的构造器中,创建Thread类的对象
        Thread t1=new Thread(runnable);
        //通过Thread类的对象调用start()
        t1.start();

        /**
         * 再启动一个线程--可以共享Runnable实例对象
         *
         */
        Thread t2=new Thread(runnable);
        t2.start();
    }
}

三、实现Callable接口

package com.fuping3.basic;

import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 * 实现多线程方式三--推荐
 * 优点:
 *      1、避免了单继承的局限性、多个线程可以共享一个Callable对象
 *      2、有返回值
 * 缺点:
 *      1、比较复杂
 *      2、访问线程必须使用Thread.currentThread()方法
 */
public class MyCallable implements Callable<Integer> {
    public Integer call() throws Exception {
        int end= new Random().nextInt(10);

        for(int i=0;i<=end;i++){
            Thread.sleep(1000);
        }
        System.out.println("Callable--当前运行线程:"+Thread.currentThread().getName()+"--结束数字:"+end);
        return end;
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //创建Callable实例对象
        MyCallable callable=new MyCallable();

        /**
         * 创建接收结果对象
         * 1、FutureTask实现Runnable、Future接口
         *      (1)实现Runnable接口,具有多线程功能
         *      (2)实现Future接口,具有接收返回值功能
         */
        FutureTask<Integer> futureTask=new FutureTask(callable);
        //须将Callable对象作为参数传递到Thread类的构造器中,创建Thread类的对象
        Thread t1=new Thread(futureTask);
        t1.setName("线程A");
        //通过Thread类的对象调用start()
        t1.start();


        /**
         * 再启动一个线程--可以共享Runnable实例对象
         *
         */
        FutureTask<Integer> futureTask2=new FutureTask(callable);
        Thread t2=new Thread(futureTask2);
        t2.setName("线程B");
        t2.start();

        //
        /**
         * 接收返回值
         *      注意点:get()为同步阻塞的,即阻塞一直到拿到返回值,程序才往下继续执行
         */
        System.out.println("线程A返回值:"+futureTask.get());
        System.out.println("线程B返回值:"+futureTask2.get());
    }
}

备注一、为什么线程的启动不直接使用run()而必须使用start()呢?

1、如果直接调用run()方法,相当于就是简单的调用一个普通方法,不会开启多线程。

2、run()的调用是在start方法中的start0()这个Native C++方法里调用的

备注二、FutureTask既可以拿到线程正常执行时返回的值,也可以拿到线程执行异常时的异常信息(举例见线程池异常处理)

四、线程池创建线程

4.1 使用线程池的好处

我们之前使用线程的时候都是使用new Thread来进行线程的创建,但是这样会有一些问题:

a. 每次new Thread新建对象性能差。
b. 线程缺乏统一管理,可能无限制新建线程,相互之间竞争,及可能占用过多系统资源导致死机或oom。
c. 缺乏更多功能,如定时执行、定期执行、线程中断。
相比new Thread,Java提供的四种线程池的好处在于:
a. 重用存在的线程,减少对象创建、消亡的开销,性能佳。
b. 提供定时执行/定期执行、并发数控制功能( 可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞)。


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值