java多线程--生成线程

  1. 继承Thread类

定义一个类继承Thread类,重写父类的run()方法

/**
 * 定义一个类继承Thread类
 * 重写父类的run方法(需要该线程执行的代码块)
 */
public class MyThread extends Thread{

    public MyThread() {}

    @Override
    public void run() {
        for(int i = 0; i<100; i++){
            System.out.println(i);
        }
    }
}

测试类

/**
 * 创建自定义线程类MyThread的实例
 * 1.为什么要重写run()方法
 * ---因为run()是用来封装被线程执行的代码
 * 2.run()与start()的区别
 * ---run():封装线程执行的代码,直接调用相当于普通方法的调用
 * ---start():启动线程;由jvm调用此线程的run()方法
 */
public class MyThreadTest {
    public static void main(String[] args) {
        MyThread my1 = new MyThread();
        MyThread my2 = new MyThread();
        // 通过start()方法执行
        my1.start();
        my2.start();
    }
}
  1. 实现Runnalbe接口

定义一个类实现Runnable接口

/**
 * 实现Runnable接口也可以实现多线程
 */
public class MyRunnable implements Runnable{

    public MyRunnable(){}

    @Override
    public void run() {
        for(int i=0; i<100; i++){
            System.out.println(i);
        }
    }
}

测试类

public class MyRunnableTest {
    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();

        // 创建Thread类的对象,实现Runnable接口的类的实例作为构造方法的参数
        Thread thread1 = new Thread(myRunnable, "高铁");
        Thread thread2 = new Thread(myRunnable, "飞机");
        thread1.start();
        thread2.start();

        // lambda表达式简洁写法
        Thread thread4 = new Thread(()->{
            for(int i=0; i<100; i++){
                System.out.println(Thread.currentThread().getName() + ":" + i);
            }
        }, "轿车");
        thread4.start();
    }
}
  1. 实现Callable接口

这里线程任务是计算0到n-1的和

/**
 * 实现callable<T>接口,结合FutureTask完成
 */
public class MyCallable implements Callable<String> {

    private int n;

    public MyCallable(int n){
        this.n = n;
    }

    @Override
    public String call() throws Exception {
        int sum = 0;
        for(int i=0; i<n; i++){
            sum += i;
        }
        return String.valueOf(sum);
    }
}

测试类

Thread类的构造器不支持Callable接口的实例,支持Runnable接口的实例

但FutureTask对象继承了RunnableFuture接口,而RunnableFurure接口继承了Runnable接口(多态)

FutureTask对象的get()方法可以等线程执行完毕后得到线程执行的结果

Callable对象任务交给FutureTask对象实现

public class MyCallableTest {
    public static void main(String[] args) {
        MyCallable myCallable1 = new MyCallable(10000);
        MyCallable myCallable2 = new MyCallable(15000);

        FutureTask<String> f1 = new FutureTask<>(myCallable1);
        FutureTask<String> f2 = new FutureTask<>(myCallable2);
        Thread thread1 = new Thread(f1);
        Thread thread2 = new Thread(f2);
        thread1.start();
        thread2.start();

        // 如果f1任务没有完成,这里代码会等待,直到线程1跑完才提取结果
        try {
            String r1 = f1.get();
            System.out.println(r1);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        }
        System.out.println("-------------------");
        try {
            String r2 = f2.get();
            System.out.println(r2);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        }
    }
}
  1. 线程池--Runnable接口任务

先写好线程任务

public class RunnableTask implements Runnable{
    @Override
    public void run() {
        for(int i=0; i<1; i++){
            System.out.println(Thread.currentThread().getName() + "   hello");
        }
    }
}

调用线程池的execute方法实现Runnable接口任务

/**
 * 线程池的参数介绍
 * public ThreadPoolExecutor(int corePoolSize, 
                             int maximumPoolSize, 
                             long keepAliveTime, 
                             TimeUint unit,
                             BlockingQueue<Runnable> workQueue, 
                             ThreadFactory threadFactory, 
                             RejectedExecutionHandler handler)
 *       corePoolSize:    指定线程池的线程数量(核心线程)             不能小于0
 *       maximumPoolSize: 指定线程池最大线程数                     最大数量 >= 核心线程数量
 *       keepAliveTime:   指定临时线程的最大存活时间                不能小于0
 *       unit:            指定存活时间的单位(秒、分、时、天)         时间单位
 *       workQueue:       指定任务队列                           不能为null
 *       threadFactory:   指定用哪个线程工厂创建线程                不能为null
 *       handler:         指定线程忙,任务满的时候,新任务来了怎么办   不能为null
 */

/**
 *     ThreadPoolExecutor.AbortPolicy           丢弃任务并抛出RejectedExecutionException异常。
                                                                                是默认的策略
 *     ThreadPoolExecutor.DiscardPolicy         丢弃任务,但是不抛出异常,这是不推荐的做法
 *     ThreadPoolExecutor.DiscardOldestPolicy   抛弃队列中等待最久的任务,然后把当前任务加入队列中
 *     ThreadPoolExecutor.CallerRunsPolicy      由主线程负责调用任务的run()方法从而绕过线程池直接执行
 */
/**
 * 临时线程什么时候创建
 *      新任务提交时发现核心线程都在忙,任务队列也满了,并且还可以创建临时线程,此时才会创建临时线程
 * 什么时候会开始拒绝任务
 *      核心线程和临时线程都在忙,任务队列也满了,新的任务过来时才会开始拒绝
 */

/**
 * 自定义一个线程池对象,并测试其特性,处理Runnable任务
 */
public class RunnableTest {
    public static void main(String[] args) {
        ExecutorService pool = new ThreadPoolExecutor(3, 5, 6, TimeUnit.SECONDS,
                                                       new ArrayBlockingQueue<>(5), 
                                                       Executors.defaultThreadFactory(), 
                                                       new ThreadPoolExecutor.AbortPolicy());

        // 给任务线程池处理
        Runnable target = new RunnableTask();
        // 核心线程3个
        pool.execute(target);
        pool.execute(target);
        pool.execute(target);
        // 任务队列5个
        pool.execute(target);
        pool.execute(target);
        pool.execute(target);
        pool.execute(target);
        pool.execute(target);
        // 再加任务创建临时线程,最多2个
        pool.execute(target);
        pool.execute(target);
        // 线程池和临时队列都满了,不创建,抛出异常,
//        pool.execute(target);
//
//        pool.shutdownNow(); // 立即关闭,即使任务没完成,会丢失任务
//        pool.shutdown(); // 会等待全部任务执行完毕后再关闭
    }
}
  1. 线程池--Callable任务

先写好线程任务

public class CallableTask implements Callable<String> {

    private int n;

    public CallableTask(int n){
        this.n = n;
    }

    @Override
    public String call() throws Exception {
        int sum = 0;
        for(int i=0; i<n; i++){
            sum += i;
        }
        return Thread.currentThread().getName() + "  " + sum;
    }
}

调用线程池的submit()方法实现callable<T>接口任务,返回Future<T>对象

public class CallableTest {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService pool = new ThreadPoolExecutor(3, 5, 6, TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(5), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());

        Future<String> f1 = pool.submit(new CallableTask(100));
        Future<String> f2 = pool.submit(new CallableTask(1000));
        Future<String> f3 = pool.submit(new CallableTask(10000));
        Future<String> f4 = pool.submit(new CallableTask(100000));
        Future<String> f5 = pool.submit(new CallableTask(1000000));

        // 依然是按顺序输出线程执行的值
        System.out.println(f1.get());
        System.out.println(f2.get());
        System.out.println(f3.get());
        System.out.println(f4.get());
        System.out.println(f5.get());
    }
    
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值