• # 说说我对于线程同步的发散性思考


    本文在 https://wkmcyz.notion.site/2cbaab3404c04513b16f40f48e0c9cb7 阅读体验更好。

    我和小辉一起散步,小辉忽然说他最近要写一个实现锁能力的机制,可以让 java 各个线程通过这个机制比较好地实现同步。

    我问他:“那用法是什么?”

    小辉说:“我这个系统,给别人调用的时候,别人只需要传递一个闭包就可以了,我会负责确保多个线程调用相同的闭包的时候,每个闭包都不是并行的。”

    我一想,这个应该比较好实现,只需要本地维护一个闭包到执行线程列表的对应关系就可以了,有新的线程到来的时候,就判断一下当前的闭包是不是正在运行,如果有的话,就等待;如果没有的话,就把这个当做第一个来运行。kotlin 代码表示的话,就是 :

    val map = HashMap<runnable : Array<Thread>>
    fun runSynchronously(thread : Thread , runnable : Runnable) {
    	if(map.contains(runnable)) {
    		map[runnable].add(thread)
    	} else {
    		map[runnable] = new ArrayList<Thread>(thread)
    		runnable.run()
    	}
    }
    
    private fun runFirst(runnable) {
    	val thread = map[runnable].first()
    	runnable.runInThread(thread)
    	runRunnableNext()
    }
    
    private fun runRunnableNextInNext(runnable :Runnable){
    	map[runnable].removeFirst()
    	runFirst(runnable)
    }
    

    然后我想了想,想到了一个问题:这样的话,我线程要么不执行,进入等待;要么就直接执行。那如果两个线程执行的时候想交替执行怎么办?

    小辉说道:“这个是个好问题,需要先想一想。”

    我说:“任务 A 如果要在中间让任务 B接着做什么的话,就需要任务 A 先完成,就是说这时候任务 A 会有一个分支,从 runnable 中 return,然后任务 B 就可以接着执行了。”

    小辉说道:“不过这样的话,任务 B 开始执行的时候,怎么知道该执行最初的逻辑还是任务 A 执行了一部分以后的逻辑呢?”

    我说:“那就加状态变量,任务 A 完成以后,把状态变量从 0 设置为 1 , 任务 B 开始的时候判断一下当前的状态,如果是 1 的话,就按照 1 的逻辑处理,然后再改为 2,任务 B 再退出,任务 A 再开始,判断状态是 3,就执行一个更新的逻辑。”

    小辉说:“好像也不是不行啊……”然后又说道:“就是有点复杂了,这样的话代码没法写了。全是逻辑判断。”

    我说:“还好呀,可以写成 switch(status) 的形式”

    小辉说道:“那我这样也行啊。你看,系统接受 runnable 以后,交给 runnable 一个 callback,runnable 可以在代码里面执行这个 callback,这个 callback 执行的结果就是让另一个线程来执行 runnable。”

    我一听,觉得很有意思,好像确实可行。但是两个还好,如果有三个的话,岂不是乱了套了,于是提出了这个问题。

    小辉说道:“那就用俩 callback,一个用来触发第二个,一个用来触发第三个线程。”

    我说道:“那这就得很多个了,万一很多线程呢?”

    小辉说道:“那就给每个线程一个列表,如果第一个线程要等待的话,就把自己加入到其中,就告诉系统说让别人运行吧,这样别的线程就能开始运行了,就同步了。”

    我点头。

    小辉继续说道:“这样的话,要是别的线程也不运行,那就都等着,就卡死。”

    我说道:“不太可能都不运行,可以先不考虑。”

    我又说道:“可以考虑多个列表,这样的话比如线程一要和线程三交流的话,就用第二个列表,线程一要和线程二交流的话,就用第一个列表。线程一做完了事情,要让线程三继续的话,就把自己放到第二个列表里,然后让线程三开始,线程三开始以后,做了一段事情,要交给线程一了,就把自己加到第二个列表里,然后让线程一开始。”

    ……

  • 相关阅读:
    excel打印预览后整个表格中按页显示虚线,打印时就会打印很多页
    4.8 自定义下拉菜单模式Spinner与setDropDownViewResource
    1.2Matlab基本语法和基本操作.
    CTime类的一个BUG
    【转载】PE_Info 之DIY
    ubuntu使用记录
    反VM测试成功
    获取MAC地址
    【转载】秒到oep,支持所有壳,包括vmp
    【转载】Make your owner PE Protector
  • 原文地址:https://www.cnblogs.com/wkmcyz/p/15841495.html
Copyright © 2020-2023  润新知