Go语言源码分析CAS的实现和Java如出一辙
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                Go语言源码分析CAS的实现和Java如出一辙
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.                        
                                看了Go的源碼CAS這塊實現和java還是類似的。
關于Java的分析參考:Java使用字節碼和匯編語言同步分析volatile,synchronized的底層實現
都是使用匯編指令:LOCK+CMPXCHGL
原因很簡單:單核肯定不能發揮Go的高并發性能,Go如果要支持多核,必然遇到并發編程數據可見性的問題,底層必然加鎖。
無鎖并不等于沒有鎖,只能說無重量級的鎖而已。
?
Go語言源碼:
Go的CAS是調用CompareAndSwapInt32,
golang中的互斥鎖定義在src/sync/mutex.go:
// Lock locks m.
// If the lock is already in use, the calling goroutine
// blocks until the mutex is available.
func (m *Mutex) Lock() {// Fast path: grab unlocked mutex.if atomic.CompareAndSwapInt32(&m.state, 0, mutexLocked) {if race.Enabled {race.Acquire(unsafe.Pointer(m))}return} 
?
無鎖操作CAS:?Compare And Swap 比較并交換。
?源碼在/src/runtime/internal/atomic/asm_amd64.s
可以看到實際上底層還是通過lock來實現,關于lock可以參考intel處理器指令。
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.// Note: some of these functions are semantically inlined
// by the compiler (in src/cmd/compile/internal/gc/ssa.go).#include "textflag.h"// bool Cas(int32 *val, int32 old, int32 new)
// Atomically:
//	if(*val == old){
//		*val = new;
//		return 1;
//	} else
//		return 0;
TEXT runtime∕internal∕atomic·Cas(SB),NOSPLIT,$0-17MOVQ	ptr+0(FP), BXMOVL	old+8(FP), AXMOVL	new+12(FP), CXLOCKCMPXCHGL	CX, 0(BX)SETEQ	ret+16(FP)RET// bool	runtime∕internal∕atomic·Cas64(uint64 *val, uint64 old, uint64 new)
// Atomically:
//	if(*val == *old){
//		*val = new;
//		return 1;
//	} else {
//		return 0;
//	}
TEXT runtime∕internal∕atomic·Cas64(SB), NOSPLIT, $0-25MOVQ	ptr+0(FP), BXMOVQ	old+8(FP), AXMOVQ	new+16(FP), CXLOCKCMPXCHGQ	CX, 0(BX)SETEQ	ret+24(FP)RETTEXT runtime∕internal∕atomic·Casuintptr(SB), NOSPLIT, $0-25JMP	runtime∕internal∕atomic·Cas64(SB)TEXT runtime∕internal∕atomic·CasRel(SB), NOSPLIT, $0-17JMP	runtime∕internal∕atomic·Cas(SB)TEXT runtime∕internal∕atomic·Loaduintptr(SB), NOSPLIT, $0-16JMP	runtime∕internal∕atomic·Load64(SB)TEXT runtime∕internal∕atomic·Loaduint(SB), NOSPLIT, $0-16JMP	runtime∕internal∕atomic·Load64(SB)TEXT runtime∕internal∕atomic·Storeuintptr(SB), NOSPLIT, $0-16JMP	runtime∕internal∕atomic·Store64(SB)TEXT runtime∕internal∕atomic·Loadint64(SB), NOSPLIT, $0-16JMP	runtime∕internal∕atomic·Load64(SB)TEXT runtime∕internal∕atomic·Xaddint64(SB), NOSPLIT, $0-24JMP	runtime∕internal∕atomic·Xadd64(SB)// bool Casp1(void **val, void *old, void *new)
// Atomically:
//	if(*val == old){
//		*val = new;
//		return 1;
//	} else
//		return 0;
TEXT runtime∕internal∕atomic·Casp1(SB), NOSPLIT, $0-25MOVQ	ptr+0(FP), BXMOVQ	old+8(FP), AXMOVQ	new+16(FP), CXLOCKCMPXCHGQ	CX, 0(BX)SETEQ	ret+24(FP)RET// uint32 Xadd(uint32 volatile *val, int32 delta)
// Atomically:
//	*val += delta;
//	return *val;
TEXT runtime∕internal∕atomic·Xadd(SB), NOSPLIT, $0-20MOVQ	ptr+0(FP), BXMOVL	delta+8(FP), AXMOVL	AX, CXLOCKXADDL	AX, 0(BX)ADDL	CX, AXMOVL	AX, ret+16(FP)RETTEXT runtime∕internal∕atomic·Xadd64(SB), NOSPLIT, $0-24MOVQ	ptr+0(FP), BXMOVQ	delta+8(FP), AXMOVQ	AX, CXLOCKXADDQ	AX, 0(BX)ADDQ	CX, AXMOVQ	AX, ret+16(FP)RETTEXT runtime∕internal∕atomic·Xadduintptr(SB), NOSPLIT, $0-24JMP	runtime∕internal∕atomic·Xadd64(SB)TEXT runtime∕internal∕atomic·Xchg(SB), NOSPLIT, $0-20MOVQ	ptr+0(FP), BXMOVL	new+8(FP), AXXCHGL	AX, 0(BX)MOVL	AX, ret+16(FP)RETTEXT runtime∕internal∕atomic·Xchg64(SB), NOSPLIT, $0-24MOVQ	ptr+0(FP), BXMOVQ	new+8(FP), AXXCHGQ	AX, 0(BX)MOVQ	AX, ret+16(FP)RETTEXT runtime∕internal∕atomic·Xchguintptr(SB), NOSPLIT, $0-24JMP	runtime∕internal∕atomic·Xchg64(SB)TEXT runtime∕internal∕atomic·StorepNoWB(SB), NOSPLIT, $0-16MOVQ	ptr+0(FP), BXMOVQ	val+8(FP), AXXCHGQ	AX, 0(BX)RETTEXT runtime∕internal∕atomic·Store(SB), NOSPLIT, $0-12MOVQ	ptr+0(FP), BXMOVL	val+8(FP), AXXCHGL	AX, 0(BX)RETTEXT runtime∕internal∕atomic·StoreRel(SB), NOSPLIT, $0-12JMP	runtime∕internal∕atomic·Store(SB)TEXT runtime∕internal∕atomic·Store64(SB), NOSPLIT, $0-16MOVQ	ptr+0(FP), BXMOVQ	val+8(FP), AXXCHGQ	AX, 0(BX)RET// void	runtime∕internal∕atomic·Or8(byte volatile*, byte);
TEXT runtime∕internal∕atomic·Or8(SB), NOSPLIT, $0-9MOVQ	ptr+0(FP), AXMOVB	val+8(FP), BXLOCKORB	BX, (AX)RET// void	runtime∕internal∕atomic·And8(byte volatile*, byte);
TEXT runtime∕internal∕atomic·And8(SB), NOSPLIT, $0-9MOVQ	ptr+0(FP), AXMOVB	val+8(FP), BXLOCKANDB	BX, (AX)RET
 
這里還有其他處理器的匯編代碼:
?其實這篇文章寫得也還可以:Golang 源代碼解析(一) 鎖機制的研究
總結
以上是生活随笔為你收集整理的Go语言源码分析CAS的实现和Java如出一辙的全部內容,希望文章能夠幫你解決所遇到的問題。