107.【并发与标准库】(四)

本文涉及的产品
语种识别,语种识别 100万字符
图片翻译,图片翻译 100张
文档翻译,文档翻译 1千页
简介: 107.【并发与标准库】
(3).强制取消定时器
package main
import (
  "fmt"
  "time"
)
func main() {
   1.第一种定义定时器
  //timer := time.NewTimer(time.Second * 2) //设置指定时间后执行管道读出
  //fmt.Printf("现在的时间是: %v\n", time.Now())
  //t1 := <-timer.C //阻塞的,指定时间到了便会读出
  //fmt.Printf("管道读出的时间是: %v\n", t1)
  //fmt.Printf("现在的时间是: %v\n", time.Now())
  //timer := time.NewTimer(time.Second * 2) //设置指定时间后执行管道读出
  //<-timer.C
  //fmt.Printf("现在的时间是: %v\n", time.Now())
  fmt.Printf("现在的时间是: %v\n", time.Now())
  timer := time.NewTimer(time.Second * 2)
  go func() {
    <-timer.C
    println("func.....")
  }()
  s := timer.Stop()  // 我们执行这个方法那么定时器就不会执行
  if s {
    println("stop....")
  }
  fmt.Printf("现在的时间是: %v\n", time.Now())
  time.Sleep(time.Second * 3)
}

(4).定时器时间的修改
package main
import (
  "fmt"
  "time"
)
func main() {
   1.第一种定义定时器
  //timer := time.NewTimer(time.Second * 2) //设置指定时间后执行管道读出
  //fmt.Printf("现在的时间是: %v\n", time.Now())
  //t1 := <-timer.C //阻塞的,指定时间到了便会读出
  //fmt.Printf("管道读出的时间是: %v\n", t1)
  fmt.Printf("现在的时间是: %v\n", time.Now())
  timer := time.NewTimer(time.Second * 2) //设置指定时间后执行管道读出
  timer.Reset(time.Second * 5)
  <-timer.C
  fmt.Printf("现在的时间是: %v\n", time.Now())
  //fmt.Printf("现在的时间是: %v\n", time.Now())
  //timer := time.NewTimer(time.Second * 2)
  //go func() {
  //  <-timer.C
  //  println("func.....")
  //}()
  //s := timer.Stop() // 我们执行这个方法那么定时器就不会执行
  //if s {
  //  println("stop....")
  //}
  //fmt.Printf("现在的时间是: %v\n", time.Now())
  //time.Sleep(time.Second * 3)
}

9.并发编程之Ticker

Timer只执行一次,Ticker可以周期的执行

(1).定义方式
1.第一种定义方式
time.NewTicker()
(2).Ticker实列
  1. 基础使用

每隔两秒打印一下

package main
import "time"
func main() {
  ticker := time.NewTicker(time.Second * 2) //每两秒执行一次
  counter := 1
  for _ = range ticker.C { //如果没有变量接受那么可以省略 :  ------>出现周期性的使用这个定时器
    println("ticker....")
    counter++
    if counter >= 5 {
      ticker.Stop()
      break
    }
  }
}


package main
import (
  "fmt"
  "time"
)
func main() {
  ticker := time.NewTicker(time.Second) //每两秒执行一次
  chanInt := make(chan int)
  go func() {
    for _ = range ticker.C { //如果没有变量接受那么可以省略 :  ------>出现周期性的使用这个定时器
      select {
      case chanInt <- 1:
        println("send: 1")
      case chanInt <- 2:
        println("send: 2")
      case chanInt <- 1:
        println("send: 3")
      }
    }
  }()
  sum := 0
  for v := range chanInt {
    fmt.Printf("receice: %v\n", v)
    sum += v
    if sum >= 10 {
      break
    }
  }
}

10.并发编程之原子变量的引入

(1).我们可以通过枷锁实现同步

为什么我实现枷锁: 联想银行的同步取钱操作。

package main
import (
  "fmt"
  "sync"
  "time"
)
/*
银行业务. 一定要考虑好保护加锁
*/
var mt sync.Mutex //定义锁
var i = 100
func add() {
  mt.Lock()  //当我上锁了,别人对我下面用的变量都不能用,
  i++
  mt.Unlock()
}
func sub() {
  mt.Lock()
  i--
  mt.Unlock()
}
func main() {
  for i := 0; i < 100; i++ {
    go add()
    go sub()
  }
  time.Sleep(time.Second * 1)
  fmt.Printf("%v", i) // 假如不上锁的话,会出现数据合演不对。
}

(2).autoic包实现乐观锁
package main
import (
  "fmt"
  "sync/atomic"
  "time"
)
/*
银行业务. 一定要考虑好保护加锁
*/
var i int32 = 100
func add() {
  // 这里的机制类似于 乐观锁的操作: 在我修改之前不允许有人修改,否则就不修改
  atomic.AddInt32(&i, 1) // 就是值int32这个类型的那个地址,每次调用添加几
}
func sub() {
  atomic.AddInt32(&i, -1)
}
func main() {
  for i := 0; i < 100; i++ {
    go add()
    go sub()
  }
  time.Sleep(time.Second * 1)
  fmt.Printf("%v", i) // 假如不上锁的话,会出现数据合演不对。
}

11.并发编程之原子操作详解

(1).automic的介绍

automic 提供的原子操作能够确保任意时刻只有一个协程对变量进行操作,善用 atomic 能够避免程序中出现大量的锁的操作。

automic常见操作有:

  • 增减
  • 载入 (读)
  • 比较并交换 cas
  • 交换
  • 存储 (写)
(2).原子性增减操作

automic包中提供了如下以Add为前缀的增减 操作:

func AddInt32(add *int32,delta int32) (new int32)
func AddInt32(add *int64,delta int64) (new int64)
func AddUInt32(add *uint32,delta uint32) (new uint32)
func AddInt32(add *uint64,delta uint64) (new uint64)
func AddInt32(add *uintptr,delta uintptr) (new uintptr)  //指针类型

增减的操作:

func add() {
  // 这里的机制类似于 乐观锁的操作: 在我修改之前不允许有人修改,否则就不修改
  atomic.AddInt32(&i, 1) // 就是值int32这个类型的那个地址,每次调用添加几
}
func sub() {
  atomic.AddInt32(&i, -1)
}
(3).原子性载入和存储

相当于银行的存钱和查看余额。

package main
import (
  "fmt"
  "sync/atomic"
  "time"
)
/*
银行业务. 一定要考虑好保护加锁
*/
var i int32 = 100
func add() {
  // 这里的机制类似于 乐观锁的操作: 在我修改之前不允许有人修改,否则就不修改
  atomic.AddInt32(&i, 1)      // 就是值int32这个类型的那个地址,每次调用添加几
  atomic.StoreInt32(&i, 200)  //存储: 相当于写的操作 当我写的时候不允许其他人写, -》类似于向银行存钱
  val := atomic.LoadInt32(&i) //载入 也就是读的操作 当我读取的时候不允许其他人读
  fmt.Printf("add-> %v\n", val)
}
func sub() {
  atomic.AddInt32(&i, -1)
  atomic.StoreInt32(&i, 200)  //存储: 相当于写的操作 当我写的时候不允许其他人写,
  val := atomic.LoadInt32(&i) //载入 也就是读的操作:  当我读取的时候不允许其他人读
  fmt.Printf("sub-> %v\n", val)
}
func main() {
  for i := 0; i < 100; i++ {
    go add()
    go sub()
  }
  time.Sleep(time.Second * 1)
  fmt.Printf("%v", i) // 假如不上锁的话,会出现数据合演不对。
}

(4).原子性比较交换

假如说: 旧值一直没有发生变化,那么就和新值发生交换返回true,否则不交换返回false。

package main
import (
  "fmt"
  "sync/atomic"
  "time"
)
/*
银行业务. 一定要考虑好保护加锁
*/
var i int32 = 100
func add() {
  // 这里的机制类似于 乐观锁的操作: 在我修改之前不允许有人修改,否则就不修改
  atomic.AddInt32(&i, 1)      // 就是值int32这个类型的那个地址,每次调用添加几
  atomic.StoreInt32(&i, 200)  //存储: 相当于写的操作 当我写的时候不允许其他人写, -》类似于向银行存钱
  val := atomic.LoadInt32(&i) //载入 也就是读的操作 当我读取的时候不允许其他人读
  fmt.Printf("add-> %v\n", val)
}
func sub() {
  atomic.AddInt32(&i, -1)
  atomic.StoreInt32(&i, 200)  //存储: 相当于写的操作 当我写的时候不允许其他人写,
  val := atomic.LoadInt32(&i) //载入 也就是读的操作:  当我读取的时候不允许其他人读
  fmt.Printf("sub-> %v\n", val)
}
func main() {
  for i := 0; i < 100; i++ {
    go add()
    go sub()
  }
  time.Sleep(time.Second * 1)
  swapInt32 := atomic.CompareAndSwapInt32(&i, 100, 200) // 就是说假如值为100那么我们就交换,假如100被修改成其他的值,那么我们就不进行交换返回false  -->也就是说有其他线程干扰了就返回flase
  fmt.Printf("%v", swapInt32)
  fmt.Printf("%v", i) // 假如不上锁的话,会出现数据合演不对。
}
相关文章
|
消息中间件
rabbitMQ集群
rabbitMQ集群
140 0
|
存储 数据安全/隐私保护 索引
接入 GitHub OAuth 登录,user表设计
接入 GitHub OAuth 登录,user表设计
125 0
|
弹性计算 关系型数据库 MySQL
LAMP环境的搭建及使用ECS服务器部署MySQL数据库
本文主要介绍如何在阿里云上快速搭建LAMP环境及使用ECS服务器部署MySQL数据库
328 0
|
3天前
|
人工智能 JavaScript 测试技术
Qwen3-Coder入门教程|10分钟搞定安装配置
Qwen3-Coder 挑战赛简介:无论你是编程小白还是办公达人,都能通过本教程快速上手 Qwen-Code CLI,利用 AI 轻松实现代码编写、文档处理等任务。内容涵盖 API 配置、CLI 安装及多种实用案例,助你提升效率,体验智能编码的乐趣。
282 100
|
3天前
|
JSON fastjson Java
FastJson 完全学习指南(初学者从零入门)
摘要:本文是FastJson的入门学习指南,主要内容包括: JSON基础:介绍JSON格式特点、键值对规则、数组和对象格式,以及嵌套结构的访问方式。FastJson是阿里巴巴开源的高性能JSON解析库,具有速度快、功能全、使用简单等优势,并介绍如何引入依赖,如何替换Springboot默认的JackJson。 核心API: 序列化:将Java对象转换为JSON字符串,演示对象、List和Map的序列化方法; 反序列化:将JSON字符串转回Java对象,展示基本对象转换方法;
|
4天前
|
Android开发 开发者 Windows
这是我设计的一种不关机,然后改造操作系统的软件设计思路2.0版本
本文介绍了在不重启系统的情况下实现操作系统改造的两种方案。第一种方案通过SLFM Recovery模式,在独立于操作系统的最高权限环境下完成系统更新与改造,并支持断电恢复与失败回滚。第二种方案采用多分区机制,通过SLFM套件在独立分区中完成系统改造,适用于可中断与不可中断服务场景,确保系统更新过程的安全与稳定。
225 132
|
4天前
|
缓存 JavaScript 前端开发
JavaScript 的三种引入方法详解
在网页开发中,JavaScript 可通过内联、内部脚本和外部脚本三种方式引入 HTML 文件,各具适用场景。本文详解其用法并附完整示例代码,帮助开发者根据项目需求选择合适的方式,提升代码维护性与开发效率。
193 110

热门文章

最新文章