java多线程和线程池(使用工厂类 Executors实现)

一、前言

进程(process)是大概念,进程里面可以有多个线程(thread)
进程是执行过程,是独立的执行路径

多任务:同时干多件事
守护线程与非守护线程
守护线程是区别于用户线程,用户线程即我们手动创建的线程,而守护线程是程序运行的时候在后台提供一种通用服务的线程垃圾回收线程就是典型的守护线程。

main是非守护线程。main线程是由java虚拟机在启动的时候创建的。main方法开始执行的时候,主线程已经创建好并在运行了。

二、三种线程的创建方式

(一)继承Thread类

流程:
1、自定义线程类继承Thread类
2、重写run()方法,编写线程执行体
3、创建线程对象,调用start()方法启动线程
创建自定义类并重写run()方法

public class MyThread extends Thread{  
    @Override  
    public void run() {  
        for (int i = 0; i < 100; i++) {  
            System.out.println("狗上山---" + i);  
        }  
    }  
}

创建线程对象,调用start()方法启动线程

public class Test {  
  
    public static void main(String[] args) {  
        MyThread myThread = new MyThread();  
        myThread.start();  
  
        for (int i = 0; i < 100; i++) {  
            System.out.println("狗下山---"+i);  
        }  
    }  
}

输出

.....
狗下山---83
狗下山---84
狗下山---85
狗下山---86
狗下山---87
狗下山---88
狗下山---89
狗下山---90
狗下山---91
狗下山---92
狗上山---89
狗上山---90
狗上山---91
狗上山---92
狗上山---93
狗上山---94
狗上山---95
狗上山---96
狗上山---97
狗上山---98
狗上山---99
狗下山---93
狗下山---94
狗下山---95
狗下山---96
狗下山---97
狗下山---98
狗下山---99

两个线程交替进行。

不建议使用Thread,因为Java单继承的局限性

(二)实现Runnable接口

1、定义MyRunnable类实现Runnable接口
2、实现run()方法,编写线程执行体
3、创建线程对象,调用start()方法启动线程

定义MyRunnable类实现Runnable接口,并实现run方法

public class MyRunnable implements Runnable{  
    @Override  
    public void run() {  
        for(int i=0; i<200; i++){  
            System.out.println("狗上山"+i);  
        }  
    }  
}

创建线程对象,并调用start()方法启动线程

public class Test {  
    public static void main(String[] args) {  
        // 创建runnable 接口的实现类对象  
        MyRunnable myRunnable = new MyRunnable();  
        // 创建线程对象,通过线程对象开启线程  
        new Thread(myRunnable).start();  
  
        for (int i = 0; i < 100; i++) {  
            System.out.println("狗子下山---"+i);  
        }  
  
    }  
}

输出

...
狗子下山---85
狗子下山---86
狗子下山---87
狗子下山---88
狗子下山---89
狗子下山---90
狗子下山---91
狗上山0
狗子下山---92
狗上山1
狗子下山---93
狗子下山---94
狗子下山---95
狗上山2
狗上山3
狗子下山---96
狗子下山---97
狗子下山---98
狗子下山---99
狗上山4
狗上山5
狗上山6
狗上山7
狗上山8
狗上山9
狗上山10
...

(三)实现Callable接口

Callable与Thread和Runable的区别在于可以返回数据。

1、实现Callable接口,需要返回值类型
2、重写call方法,需要抛出异常
3、创建目标对象
4、创建执行服务:ExecutorService service = Executors.newFixedThreadPool(1);
5、提交执行:

Future<Boolean> result1 = ser.submit(t1);

6、获取结果:boolean r1 = result1.get()
7、关闭服务: service.shutdownNow();

实现接口、重写call

public class MyCallable implements Callable {  
    int num;  
    public MyCallable(int num){  
        this.num = num;  
    }  
    @Override  
    public Boolean call() throws Exception {  //可以设置返回数据类型
        System.out.println("狗上山==="+num);  
        return true;    }  
}

创建目标对象、创建执行服务、提交执行、获取结果、关闭服务

public class Test {  
    public static void main(String[] args) throws ExecutionException, InterruptedException {  
  
        // 创建目标对象  
        MyCallable myCallable1 = new MyCallable(1);  
        MyCallable myCallable2 = new MyCallable(2);  
        MyCallable myCallable3 = new MyCallable(3);  
  
        // 创建线程池执行服务  
        ExecutorService service = Executors.newFixedThreadPool(3);  
  
        // 提交执行  
        Future<Boolean> s1 = service.submit(myCallable1);  
        Future<Boolean> s2 = service.submit(myCallable2);  
        Future<Boolean> s3 = service.submit(myCallable3);  
  
        // 获取结果  
        boolean ss1 = s1.get();  
        boolean ss2 = s2.get();  
        boolean ss3 = s3.get();  
  
        // 关闭服务  
        service.shutdown();  
  
  
        System.out.println(ss1 + "----" + ss2 + "----" + ss3);  
  
    }  
}

输出

三、线程池

创建线程池的方式多种多样,大家可以根据需求进行填写

选择自定义线程的实现方式,我这里选择的是Runnable
1、实现Runnable接口
2、重写run方法
3、创建目标对象
4、创建执行服务:ExecutorService service = Executors.newFixedThreadPool(3);
5、提交执行:

Future<Boolean> result1 = service.execute(t1);

6、获取结果:boolean r1 = result1.get()
7、关闭服务: service.shutdownNow();

实现接口和重写方法

public class MyRunnable implements Runnable{  
    String name;  
    public MyRunnable(String name){  
        this.name = name;  
    }  
    @Override  
    public void run() {  
        System.out.println(Thread.currentThread().getName() + name + "上山");  
    }  
}

测试

public class Test {  
    public static void main(String[] args) {  
        // 创建目标对象  
        MyRunnable r1 = new MyRunnable("狗");  
        MyRunnable r2 = new MyRunnable("猫");  
        MyRunnable r3 = new MyRunnable("鸟");  
  
        // 创建线程池执行服务  
        ExecutorService service = Executors.newFixedThreadPool(3);  
  
        // 执行服务,execute只可以执行Runnable  
        service.execute(r1);  
        service.execute(r2);  
        service.execute(r3);  
  
        // 关闭服务  
        service.shutdown();  
    }  
}

输出

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值