Java学习40-Java 多线程安全:线程池

发布于:2024-04-03 ⋅ 阅读:(102) ⋅ 点赞:(0)

创建多线程的方式四:使用线程池(这也是真正开发常选择的方式)

线程池的好处:

提高了程序执行效率(因为线程已经提前创建好了)
提高了资源的复用率(因为执行完的线程并未销毁,二是可以继续执行其他的任务)
可以设置相关的参数,对线程池中的线程使用进行资源管理

ThreadPool + Runnable

格式归纳:

class A implements Runnable{@override run({XXX})}
class B implements Runnable{@override run({XXX})}

public class ThreadPool{
	public static void main(String[] args) {
ExecutorService x = Executors.newFixedThreadPool(N);//提供N个线程池


//ExecutorService是一个接口,它表示一个执行器,用于管理和控制异步任务的执行。
//x 是一个变量,用于存储对 ExecutorService 对象的引用。
//Executors是一个工具类,提供了一系列静态工厂方法,用于创建不同类型的线程池。
//newFixedThreadPool(N) 是 Executors 类中的一个静态方法,它用于创建一个固定大小为N的线程池。

//当这句代码执行后,x 变量就会持有一个指向新创建的固定大小线程池的引用。通过这个引用,你可以向线程池提交任务(Runnable 或 Callable 对象),控制线程池的关闭等。

x.execute(new A());
x.execute(new B());
x.shutdown(); //用完了及时关闭,养成良好的习惯

	}

线程池程序举例(两个线程,一个输出奇数。一个输出偶数)-使用Runnable接口完成:

package ThreadPool;

import java.lang.reflect.Executable;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

//创建并使用多线程的第四种方法:使用线程池

//第一个线程打印偶数
 class NumberThread implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            if(i%2 == 0){
                System.out.println(Thread.currentThread().getName()+":"+i);
            }
        }

    }
}

//第二个线程 打印奇数
 class NumberThread1 implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            if(i%2 != 0){
                System.out.println(Thread.currentThread().getName()+":"+i);
            }
        }

    }
}


public class ThreadPool {
    public static void main(String[] args) {
        //提供指定线程数量的线程池
        ExecutorService x  = Executors.newFixedThreadPool(10);

          //下面是一个强制类型转换
        //这行代码尝试将x(一个ExecutorService对象)强制转换为ThreadPoolExecutor类型,并将其赋值给变量y。
        // 这通常是不安全的,因为ExecutorService是一个接口,可以有多种实现,而ThreadPoolExecutor只是其中之一。
        // 虽然在这个特定的例子中,通过Executors.newFixedThreadPool创建的ExecutorService对象实际上是一个ThreadPoolExecutor实例,
        // 但这种强制类型转换仍然是不推荐的,因为它降低了代码的健壮性。
        // 如果将来x由不同的ExecutorService实现提供,这行代码将会抛出ClassCastException。
        // 此处创建y是为了配合下一行的调整线程池大小
        
        //ThreadPoolExecutor y =(ThreadPoolExecutor) x;

        //可以后续手动调整线程池的属性
        //System.out.println(x.getClass()); //ThreadPoolExecutor
        //y.setMaximumPoolSize(15);//可再次设置线程池中线程数的上限


        //下面就是具体想让线程池执行哪些事情,调哪个class里的run,直接调就行
        //执行指定线程的操作,需要提供实现Runnable接口或Callable接口实现类的对象
        x.execute(new NumberThread());//适用于Runnable
        x.execute(new NumberThread1());//适用于Runnable

        //x.submit(Callable callable); //(本例子中是Runnable方式),类似的,也可以使用Callable接口方式(上面对应的Thread调用模块那也需要改)
        // 若需要使用Callable接口方式的返回值,用submit调用


        //关闭池子
        x.shutdown();

    }
}

运行结果:

pool-1-thread-1:0
pool-1-thread-1:2
pool-1-thread-1:4
pool-1-thread-1:6
pool-1-thread-1:8
pool-1-thread-1:10
pool-1-thread-1:12
pool-1-thread-1:14
pool-1-thread-1:16
pool-1-thread-1:18
pool-1-thread-1:20
pool-1-thread-1:22
pool-1-thread-1:24
pool-1-thread-1:26
pool-1-thread-1:28
pool-1-thread-1:30
pool-1-thread-1:32
pool-1-thread-1:34
pool-1-thread-1:36
pool-1-thread-1:38
pool-1-thread-1:40
pool-1-thread-1:42
pool-1-thread-1:44
pool-1-thread-1:46
pool-1-thread-1:48
pool-1-thread-1:50
pool-1-thread-1:52
pool-1-thread-1:54
pool-1-thread-1:56
pool-1-thread-1:58
pool-1-thread-1:60
pool-1-thread-1:62
pool-1-thread-2:1
pool-1-thread-2:3
pool-1-thread-2:5
pool-1-thread-2:7
pool-1-thread-2:9
pool-1-thread-2:11
pool-1-thread-2:13
pool-1-thread-2:15
pool-1-thread-2:17
pool-1-thread-2:19
pool-1-thread-2:21
pool-1-thread-2:23
pool-1-thread-2:25
pool-1-thread-2:27
pool-1-thread-2:29
pool-1-thread-2:31
pool-1-thread-2:33
pool-1-thread-2:35
pool-1-thread-2:37
pool-1-thread-2:39
pool-1-thread-2:41
pool-1-thread-2:43
pool-1-thread-2:45
pool-1-thread-2:47
pool-1-thread-2:49
pool-1-thread-2:51
pool-1-thread-2:53
pool-1-thread-2:55
pool-1-thread-2:57
pool-1-thread-2:59
pool-1-thread-2:61
pool-1-thread-2:63
pool-1-thread-2:65
pool-1-thread-2:67
pool-1-thread-2:69
pool-1-thread-2:71
pool-1-thread-2:73
pool-1-thread-2:75
pool-1-thread-2:77
pool-1-thread-2:79
pool-1-thread-2:81
pool-1-thread-2:83
pool-1-thread-2:85
pool-1-thread-2:87
pool-1-thread-2:89
pool-1-thread-2:91
pool-1-thread-2:93
pool-1-thread-2:95
pool-1-thread-2:97
pool-1-thread-2:99
pool-1-thread-1:64
pool-1-thread-1:66
pool-1-thread-1:68
pool-1-thread-1:70
pool-1-thread-1:72
pool-1-thread-1:74
pool-1-thread-1:76
pool-1-thread-1:78
pool-1-thread-1:80
pool-1-thread-1:82
pool-1-thread-1:84
pool-1-thread-1:86
pool-1-thread-1:88
pool-1-thread-1:90
pool-1-thread-1:92
pool-1-thread-1:94
pool-1-thread-1:96
pool-1-thread-1:98

Process finished with exit code 0

ThreadPool + Callable

当然也可以使用implements Callable构建,call结构可以有返回值,调用时候稍有不同。
调用结构对应归纳为:

class A implements Callable{call(){XXX return result_a}} 

public class 主程序 {
public static void main(String[] args) {
//提交N个线程池
 ExecutorService x = Executors.newFixedThreadPool(N);

       
        Future f_obj= x.submit(new A()); //创建Callable任务并且提交到线程池

        f_obj.get(); //获取call结构的return值result_a

        //System.out.println(f_obj.get());//也可以打印输出这个值

        x.shundown();//用完了及时关闭
}
}

具体代码如下:

package ThreadPool;

import java.util.concurrent.*;

public class OddEvenNum {


    public static void main(String[] args) {
        ExecutorService x = Executors.newFixedThreadPool(4);


        //创建Callable任务并且提交到线程池
        Future f_e= x.submit(new Even());
        Future f_o= x.submit(new Odd());



        try {
            System.out.println(f_e.get());
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        }
        try {
            System.out.println(f_o.get());
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        }


        x.shutdown();
    }
}

class Odd implements Callable {
private int sum =0;
    @Override
    public Object call() {
        for (int i = 0; i <= 100; i++) {
            if(i%2==0){
                System.out.println(Thread.currentThread().getName()+" is printing Odd numer: "+i);
                sum+=i;
            }
        }
        return sum;


    }
}

class Even implements Callable{
private int sum = 0;
    @Override
    public Object call() {
        for (int i = 0; i <= 100; i++) {
            if(i%2!=0){
                System.out.println(Thread.currentThread().getName()+" is printing Even numer: "+i);
                sum+=i;
            }

        }
        return sum;

    }
}

运行结果:


pool-1-thread-2 is printing Odd numer: 0
pool-1-thread-2 is printing Odd numer: 2
pool-1-thread-2 is printing Odd numer: 4
pool-1-thread-2 is printing Odd numer: 6
pool-1-thread-2 is printing Odd numer: 8
pool-1-thread-2 is printing Odd numer: 10
pool-1-thread-2 is printing Odd numer: 12
pool-1-thread-2 is printing Odd numer: 14
pool-1-thread-2 is printing Odd numer: 16
pool-1-thread-2 is printing Odd numer: 18
pool-1-thread-2 is printing Odd numer: 20
pool-1-thread-2 is printing Odd numer: 22
pool-1-thread-2 is printing Odd numer: 24
pool-1-thread-1 is printing Even numer: 1
pool-1-thread-1 is printing Even numer: 3
pool-1-thread-1 is printing Even numer: 5
pool-1-thread-1 is printing Even numer: 7
pool-1-thread-1 is printing Even numer: 9
pool-1-thread-1 is printing Even numer: 11
pool-1-thread-1 is printing Even numer: 13
pool-1-thread-1 is printing Even numer: 15
pool-1-thread-1 is printing Even numer: 17
pool-1-thread-2 is printing Odd numer: 26
pool-1-thread-2 is printing Odd numer: 28
pool-1-thread-2 is printing Odd numer: 30
pool-1-thread-2 is printing Odd numer: 32
pool-1-thread-2 is printing Odd numer: 34
pool-1-thread-2 is printing Odd numer: 36
pool-1-thread-2 is printing Odd numer: 38
pool-1-thread-2 is printing Odd numer: 40
pool-1-thread-2 is printing Odd numer: 42
pool-1-thread-2 is printing Odd numer: 44
pool-1-thread-2 is printing Odd numer: 46
pool-1-thread-2 is printing Odd numer: 48
pool-1-thread-2 is printing Odd numer: 50
pool-1-thread-2 is printing Odd numer: 52
pool-1-thread-2 is printing Odd numer: 54
pool-1-thread-2 is printing Odd numer: 56
pool-1-thread-2 is printing Odd numer: 58
pool-1-thread-2 is printing Odd numer: 60
pool-1-thread-2 is printing Odd numer: 62
pool-1-thread-2 is printing Odd numer: 64
pool-1-thread-2 is printing Odd numer: 66
pool-1-thread-2 is printing Odd numer: 68
pool-1-thread-2 is printing Odd numer: 70
pool-1-thread-2 is printing Odd numer: 72
pool-1-thread-2 is printing Odd numer: 74
pool-1-thread-2 is printing Odd numer: 76
pool-1-thread-2 is printing Odd numer: 78
pool-1-thread-2 is printing Odd numer: 80
pool-1-thread-2 is printing Odd numer: 82
pool-1-thread-2 is printing Odd numer: 84
pool-1-thread-2 is printing Odd numer: 86
pool-1-thread-2 is printing Odd numer: 88
pool-1-thread-2 is printing Odd numer: 90
pool-1-thread-2 is printing Odd numer: 92
pool-1-thread-2 is printing Odd numer: 94
pool-1-thread-2 is printing Odd numer: 96
pool-1-thread-2 is printing Odd numer: 98
pool-1-thread-2 is printing Odd numer: 100
pool-1-thread-1 is printing Even numer: 19
pool-1-thread-1 is printing Even numer: 21
pool-1-thread-1 is printing Even numer: 23
pool-1-thread-1 is printing Even numer: 25
pool-1-thread-1 is printing Even numer: 27
pool-1-thread-1 is printing Even numer: 29
pool-1-thread-1 is printing Even numer: 31
pool-1-thread-1 is printing Even numer: 33
pool-1-thread-1 is printing Even numer: 35
pool-1-thread-1 is printing Even numer: 37
pool-1-thread-1 is printing Even numer: 39
pool-1-thread-1 is printing Even numer: 41
pool-1-thread-1 is printing Even numer: 43
pool-1-thread-1 is printing Even numer: 45
pool-1-thread-1 is printing Even numer: 47
pool-1-thread-1 is printing Even numer: 49
pool-1-thread-1 is printing Even numer: 51
pool-1-thread-1 is printing Even numer: 53
pool-1-thread-1 is printing Even numer: 55
pool-1-thread-1 is printing Even numer: 57
pool-1-thread-1 is printing Even numer: 59
pool-1-thread-1 is printing Even numer: 61
pool-1-thread-1 is printing Even numer: 63
pool-1-thread-1 is printing Even numer: 65
pool-1-thread-1 is printing Even numer: 67
pool-1-thread-1 is printing Even numer: 69
pool-1-thread-1 is printing Even numer: 71
pool-1-thread-1 is printing Even numer: 73
pool-1-thread-1 is printing Even numer: 75
pool-1-thread-1 is printing Even numer: 77
pool-1-thread-1 is printing Even numer: 79
pool-1-thread-1 is printing Even numer: 81
pool-1-thread-1 is printing Even numer: 83
pool-1-thread-1 is printing Even numer: 85
pool-1-thread-1 is printing Even numer: 87
pool-1-thread-1 is printing Even numer: 89
pool-1-thread-1 is printing Even numer: 91
pool-1-thread-1 is printing Even numer: 93
pool-1-thread-1 is printing Even numer: 95
pool-1-thread-1 is printing Even numer: 97
pool-1-thread-1 is printing Even numer: 99
2500
2550

Process finished with exit code 0


网站公告

今日签到

点亮在社区的每一天
去签到