服务器之家

服务器之家 > 正文

Java手写线程池的实现方法

时间:2021-04-14 11:41     来源/作者:爱吃盐的猿

本文实例为大家分享了Java手写线程池的实现代码,供大家参考,具体内容如下

1.线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池线程都是后台线程。

2.线程池简易架构

Java手写线程池的实现方法

3.简易线程池代码(自行优化)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import java.util.List;
 
/**
 * 线程接口
 *
 * @Author yjian
 * @Date 14:49 2017/10/14
 **/
public interface IThreadPool {
 //加入任务
 void execute(Runnable task);
 
 //加入任务
 void execute(Runnable[] tasks);
 
 //加入任务
 void execute(List<Runnable> tasks);
 
 //销毁线程
 void destroy();
}

 

?
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
 
/**
 * 线程实现类(简易实现,自行优化.提供思路)
 *
 * @Author yjian
 * @Date 14:49 2017/10/14
 **/
@SuppressWarnings("ALL")
public class ThreadPoolImpl implements IThreadPool {
 //默认开启线程个数
 static int WORKER_NUMBER = 5;
 //完成任务线程数 可见性
 static volatile int sumCount = 0;
 //任务队列 list非线程安全,可以优化为BlockingQueue
 static List<Runnable> taskQueue = new LinkedList<Runnable>();
 //线程工作组
 WorkerThread[] workThreads;
 //原子性
 static AtomicLong threadNum = new AtomicLong();
 
 static ThreadPoolImpl threadPool;
 
 //构造方法
 public ThreadPoolImpl() {
  this(WORKER_NUMBER);
 }
 
 public ThreadPoolImpl(int workerNum) {
  this.WORKER_NUMBER = workerNum;
  //开辟工作线程空间
  workThreads = new WorkerThread[WORKER_NUMBER];
  //开始创建工作线程
  for (int i = 0; i < WORKER_NUMBER; i++) {
   workThreads[i] = new WorkerThread();
   Thread thread = new Thread(workThreads[i], "ThreadPool-worker" + threadNum.incrementAndGet());
   System.out.println("初始化线程数" + (i + 1) + "---------当前线程名称:" + thread.getName());
   thread.start();
  }
 }
 
 @Override
 public String toString() {
  return "工作线程数量为" + WORKER_NUMBER
    + "已完成的任务数" + sumCount +
    "等待任务数量" + taskQueue.size();
 }
 
 
 //获取线程池
 public static IThreadPool getThreadPool() {
  return getThreadPool(WORKER_NUMBER);
 }
 
 public static IThreadPool getThreadPool(int workerNum) {
  //容错性,如果小于等于0就默认线程数
  if (workerNum <= 0) {
   workerNum = WORKER_NUMBER;
  }
  if (threadPool == null) {
   threadPool = new ThreadPoolImpl(workerNum);
  }
  return threadPool;
 }
 
 
 @Override
 public void execute(Runnable task) {
  synchronized (taskQueue) {
   taskQueue.add(task);
   taskQueue.notifyAll();
  }
 }
 
 @Override
 public void execute(Runnable[] tasks) {
  synchronized (taskQueue) {
   for (Runnable task : tasks) {
    taskQueue.add(task);
   }
   taskQueue.notifyAll();
  }
 }
 
 @Override
 public void execute(List<Runnable> tasks) {
  synchronized (taskQueue) {
   for (Runnable task : tasks) {
    taskQueue.add(task);
   }
   taskQueue.notifyAll();
  }
 }
 
 @Override
 public void destroy() {
  //循环是否还存在任务,如果存在等待20毫秒处理时间
  while (!taskQueue.isEmpty()) {
   try {
    Thread.sleep(20);
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }
  //如果任务队列已处理完成,销毁线程,清空任务
  for (int i = 0; i < WORKER_NUMBER; i++) {
   workThreads[i].setWorkerFlag();
   workThreads[i] = null;
  }
  threadPool = null;
  taskQueue.clear();
 }
 
 //创建工作线程池
 class WorkerThread extends Thread {
  //用来标识当前线程属于活动可用状态
  private boolean isRunning = true;
 
  @Override
  public void run() {
   Runnable runnable = null;
   //死循环
   while (isRunning) {
    //非线程安全,所以采用同步锁
    synchronized (taskQueue) {
     while (isRunning && taskQueue.isEmpty()) {
      try {
       //如果任务队列为空,等待20毫秒 监听任务到达
       taskQueue.wait(20);
      } catch (Exception e) {
       e.printStackTrace();
      }
     }
     //任务队列不为空
     if (!taskQueue.isEmpty()) {
      runnable = taskQueue.remove(0);//获取第一个任务
     }
    }
    if (runnable != null) {
     runnable.run();
    }
    sumCount++;
    runnable = null;
   }
  }
 
  //销毁线程
  public void setWorkerFlag() {
   isRunning = false;
  }
 }
}
?
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
import java.util.ArrayList;
import java.util.List;
 
/**
 * 测试类
 *
 * @Author yjian
 * @Date 15:37 2017/10/14
 **/
public class ThreadPoolTest {
 
 
 public static void main(String[] args) {
  //获取线程池
  IThreadPool t = ThreadPoolImpl.getThreadPool(20);
 
  List<Runnable> taskList = new ArrayList<Runnable>();
  for (int i = 0; i < 100; i++) {
   taskList.add(new Task());
  }
  //执行任务
  t.execute(taskList);
  System.out.println(t);
  //销毁线程
  t.destroy();
  System.out.println(t);
 }
 
 static class Task implements Runnable {
 
  private static volatile int i = 1;
 
  @Override
  public void run() {
   System.out.println("当前处理的线程:" + Thread.currentThread().getName() + " 执行任务" + (i++) + " 完成");
  }
 }
 
}

对spring源码研究的,仔细查看代码用了哪几种spring常用的模式。写程序的规范应该和spring一样。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

标签:

相关文章

热门资讯

2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
yue是什么意思 网络流行语yue了是什么梗
yue是什么意思 网络流行语yue了是什么梗 2020-10-11
背刺什么意思 网络词语背刺是什么梗
背刺什么意思 网络词语背刺是什么梗 2020-05-22
Intellij idea2020永久破解,亲测可用!!!
Intellij idea2020永久破解,亲测可用!!! 2020-07-29
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总 2020-11-13
返回顶部