利用go通道channel实现互斥锁

本文介绍了如何利用 Go 语言的通道特性创建一个大小为 1 的缓冲通道,以此模拟加锁与解锁过程,实现在并发环境中的任务顺序执行。通过例子展示了 Lock、TryLock 和 Unlock 方法的使用,以及在 main 函数中协程调度的执行顺序。
摘要由CSDN通过智能技术生成

利用通道的阻塞特性,可以创建一个缓冲大小为1的通道,只有第一个往通道里放数据的协程会成功,其它的只能阻塞等待,这个过程相当于加锁,获得锁的协程任务执行完毕后往通道中取出数据就是解锁,然后其他的协程就可以继续获得锁了,实现代码如下:

package main

import (
	"fmt"
	"time"
)


type Lock struct {
	ch chan struct{}
}

func NewLock() *Lock {
	l:=&Lock{}
	l.ch = make(chan struct{},1)
	return l
}

//获取锁,未获取到一直阻塞
func (l *Lock) Lock()  {
	l.ch <- struct{}{}
}

//尝试获取锁,无论是否获取到锁,立即返回
func (l *Lock) TryLock() bool {
	select {
	case l.ch <- struct{}{}:
		return true
	default:
		return false
	}
}

//尝试获取锁,在规定时间内仍未获得锁则返回
func (l *Lock) TryLockWithTimeout(t time.Duration) bool {
	timer:=time.NewTimer(t)
	select {
	case l.ch <- struct{}{}:
		timer.Stop()
		return true
	case <-timer.C:
		return false
	}
}

//解锁
func (l *Lock)  Unlock()  {
	select {
	case <- l.ch:
		return
	default:
	}
}

var l *Lock

func main() {
	l = NewLock()
	go task(1)
	go task(2)
	go task(3)

	time.Sleep(8*time.Second)

}

func task(i int) {
	l.Lock()
	defer l.Unlock()

	fmt.Println("任务",i,"开始执行")
	time.Sleep(2*time.Second)
	fmt.Println("任务",i,"执行完毕")
}

执行结果:

任务 1 开始执行
任务 1 执行完毕
任务 2 开始执行
任务 2 执行完毕
任务 3 开始执行
任务 3 执行完毕

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值