背景:在上一篇中,作为班主任的你,对班级的管理初见成效,但理想和现实总有差距,理想情况下,从接手一个调皮的班级到班级的管理井井有条,然而,现实是:班级里少不了调皮的学生,对于这样的情况,应该怎么办呢?本文仅以讲解技术为出发点,不代表教育观点。
有一个万不得已的办法是:听话的学生和调皮的学生互不干扰。
对应为线程,就是对线程进行分组,按组执行。
在我们的假定场景中,张三、李四是听话的学生,自然是一组,王五是一组,三个学生需要完成一组任务,同时我们希望同一组的张三、李四共同完成任务。
我们把上述业务场景拆分为技术片段:张三、李四分组 + 张三、李四共同完成任务+王五单独一组+王五肚子完成自己的任务
分组的概念很好理解,那么:张三、李四共同完成任务意味着什么呢?直白的说,就是张三、王五对应的线程不再各自持有互斥锁,变为普通线程,以便可以交替执行。
为了进一步演示这个场景,我们引入了任务的工具类:init.go,代码如下:
package concurrent var task = map[int]string{1:"起床", 2:"洗漱", 3:"吃饭"} // 班主任规定的一组任务
模拟班级的代码如下:
package concurrent import ( "fmt" "sync" "time" ) // 在这个例子里,我们希望王五不要捣乱,等张三和李四竞争完,王五再出现 // 即:张三和李四先竞争,王五最后独自行动 var mutexImprove sync.Mutex // 创建一个互斥锁 func ThreadMutexImporveZhangSan(wg *sync.WaitGroup) { defer wg.Done() for i :=1; i <= 3; i++ { fmt.Println("张三:", task[i]) time.Sleep(time.Millisecond * 500) } } func ThreadMutexImproveLiSi(wg *sync.WaitGroup) { defer wg.Done() for i := 1; i <= 3; i++ { fmt.Println("李四:", task[i]) time.Sleep(time.Millisecond * 500) } } func ThreadMutexImproveWangWu() { for i := 1; i <= 3; i++ { fmt.Println("王五*:", task[i]) time.Sleep(time.Millisecond * 500) } }
为了适应线程分组,main.go的代码需要引入sync.WaitGroup,代码如下:
wgImprove.Add(2) go concurrent.ThreadMutexImporveZhangSan(&wgImprove) go concurrent.ThreadMutexImproveLiSi(&wgImprove) wgImprove.Wait() go concurrent.ThreadMutexImproveWangWu()
此时,执行代码,可以看到张三、李四是一组的,并且是交替执行,王五是独立的,这也就意味着我们完成了班级的管理目标。