hbf548

多看源码多读书

0%

线程池

使用背景:经常创建和销毁、使用量特别大的资源,比如并发情况下的线程,对性能影响很大。
思路:提前创建好多个线程,放入线程池中,使用时直接获取,使用完放回池中。可以避免频繁创建销毁、实现重复利用。类似生活中的公共交通工具。

使用线程池的好处

好处:

  • 提高响应速度(减少了创建新线程的时间)
  • 降低资源消耗(重复利用线程池中线程,不需要每次都创建)
  • 便于线程管理(…
    • corePoolSize: 核心池的大小
    • maximumPoolSize:最大线程数
    • keepAliveTime:线程没有任务时最多保持多长时间后会终止

使用线程池

  • JDK 5.0起提供了线程池相关APl: ExecutorServiceExecutors
  • ExecutorService真正的线程池接口。常见子类ThreadPoolExecutor
    • void execute(Runnable command) :执行任务/命令,没有返回值,一般用来执行Runnable
    • Future submit(Callable task):执行任务,有返回值,一般又来执行Callable
    • void shutdown() :关闭连接池
  • Executors: 工具类、线程池的工厂类,用于创建并返回不同类型的线程池

方式一:实现Runnable接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class Testpool {

public static void main(String[] args) {
//1.创建线程池
//newFixedThreadPool 参数是:池子的大小
ExecutorService service = Executors.newFixedThreadPool(10);
service.execute(new MyThread());
service.execute(new MyThread());
service.execute(new MyThread());
service.execute(new MyThread());

//关闭连接
service.shutdown();
}

}

class MyThread implements Runnable{

@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}
image.png

可以看见4个池子

方式二:实现Callable接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class NumThread implements Callable {
@Override
public Object call() throws Exception {
return Thread.currentThread().getName();
}
}

public class Test{
public static void main(String[] args) throws ExecutionException, InterruptedException {

ExecutorService service = Executors.newFixedThreadPool(3);
Future submit = service.submit(new NumThread());
Future submit1 = service.submit(new NumThread());
Future submit2 = service.submit(new NumThread());

System.out.println(submit.get());
System.out.println(submit1.get());
System.out.println(submit2.get());
service.shutdown();

}
}
image.png

创建线程池的4种方法

1
2
3
4
5
6
7
8
9
10
11
12
13
创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
容量大小为:Integer.MAX_VALUE
1.newCachedThreadPool

创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
2.newFixedThreadPool

创建一个定长线程池,支持定时及周期性任务执行。
3.newScheduledThreadPool

//创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,
保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
4..newSingleThreadExecutor
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class NumThread1 implements Runnable {
@Override
public Object call() throws Exception {
return Thread.currentThread().getName();
}

/* @Override
public void run() {
System.out.println(Thread.currentThread().getName());
}*/
}

public class Cached{
public static void main(String[] args) throws ExecutionException, InterruptedException {

ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
cachedThreadPool.submit(new NumThread1());
cachedThreadPool.submit(new NumThread1());
cachedThreadPool.submit(new NumThread1());
cachedThreadPool.submit(new NumThread1());
cachedThreadPool.shutdown();
}
}
image.png
1
2
3
4
5
6
ExecutorService cachedThreadPool = Executors.newScheduledThreadPool(3);
cachedThreadPool.submit(new NumThread1());
cachedThreadPool.submit(new NumThread1());
cachedThreadPool.submit(new NumThread1());
cachedThreadPool.submit(new NumThread1());
cachedThreadPool.shutdown();
image.png
1
2
3
4
5
6
ExecutorService cachedThreadPool = Executors.newSingleThreadExecutor();
cachedThreadPool.submit(new NumThread1());
cachedThreadPool.submit(new NumThread1());
cachedThreadPool.submit(new NumThread1());
cachedThreadPool.submit(new NumThread1());
cachedThreadPool.shutdown();


image.png

总结

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
public class ThreadNew {

public static void main(String[] args) throws ExecutionException, InterruptedException {
new MyThread1().start();

new Thread(new MyThread2()).start();

/*FutureTask<Integer> futureTask = new FutureTask<Integer>(new MyCallable());
new Thread(futureTask).start();

try {

System.out.println(futureTask.get());
} catch (InterruptedException e) {
e.printStackTrace();
}*/

ExecutorService service = Executors.newFixedThreadPool(3);
Future submit = service.submit(new MyCallable());
System.out.println(submit.get());

}

}

class MyThread1 extends Thread {
@Override
public void run() {
System.out.println("1");
}
}

class MyThread2 implements Runnable {
@Override
public void run() {
System.out.println("2");
}
}

class MyCallable implements Callable {

@Override
public Integer call() throws Exception {
return 100;
}
}
image.png