package main
import (
"fmt"
"log"
"strconv"
"sync"
)
type Runnable interface {
run()
}
type Task struct {
name string
fun func(string)
}
type Worker struct {
id string
taskQueue chan Runnable
wg *sync.WaitGroup
}
type WorkerPool struct {
workersSize int
workers []*Worker
jobQueue chan Runnable
workerDispatcher chan *Worker
wg sync.WaitGroup
}
func (task *Task) run() {
task.fun(task.name)
}
func (w *Worker) Start() {
go func() {
for {
select {
case wJob,ok := <- w.taskQueue:{
if ok {
wJob.run()
}else{
w.wg.Done()
return
}
}
}
}
}()
}
func (w *Worker) Stop() {
close(w.taskQueue)
}
func (pool *WorkerPool) newWorker(Id string, taskChSize int) *Worker {
log.Printf("新建线程:%s \n", Id)
return &Worker{
id:Id,
taskQueue: make(chan Runnable, taskChSize),
wg:&pool.wg,
}
}
func NewPool(maxWorkers, workerTaskSize, maxQueue int) *WorkerPool {
JobQueue := make(chan Runnable, maxQueue)
workerQueue := make(chan *Worker, maxWorkers)
pool := WorkerPool{
workersSize: maxWorkers,
jobQueue: JobQueue,
workerDispatcher: workerQueue,
wg:sync.WaitGroup{},
}
pool.init(workerTaskSize)
return &pool
}
func (pool *WorkerPool) init(workerTaskSize int) {
for i := 0; i < pool.workersSize; i++ {
worker := pool.newWorker(fmt.Sprintf("work-%s", strconv.Itoa(i)), workerTaskSize)
pool.workers = append(pool.workers,worker)
pool.workerDispatcher <- worker
worker.Start()
}
pool.wg.Add(pool.workersSize)
go pool.start()
}
func (pool *WorkerPool) start() {
for {
select {
case wJob, Ok := <-pool.jobQueue:
if Ok {
worker := <- pool.workerDispatcher
worker.taskQueue <- wJob
pool.workerDispatcher <- worker
} else {
for _,worker := range pool.workers{
worker.Stop()
}
return
}
}
}
}
func (pool *WorkerPool) addTask(job Runnable) {
pool.jobQueue <- job
}
func (pool *WorkerPool) shutdown() {
close(pool.jobQueue)
pool.wg.Wait()
}
func main() {
pool := NewPool(2, 10, 100)
for i := 0; i < 5; i++ {
task := Task{fmt.Sprintf("任务%d", i+1),func(p string){log.Println(p,"执行完成")}}
pool.addTask(&task)
log.Println("添加任务",i)
}
pool.shutdown()
}
2018/09/12 18:57:30 新建线程:work-0
2018/09/12 18:57:30 新建线程:work-1
2018/09/12 18:57:30 添加任务 0
2018/09/12 18:57:30 添加任务 1
2018/09/12 18:57:30 添加任务 2
2018/09/12 18:57:30 添加任务 3
2018/09/12 18:57:30 添加任务 4
2018/09/12 18:57:30 任务1 执行完成
2018/09/12 18:57:30 任务3 执行完成
2018/09/12 18:57:30 任务5 执行完成
2018/09/12 18:57:30 任务2 执行完成
2018/09/12 18:57:30 任务4 执行完成
Process finished with exit code 0