`
ihuashao
  • 浏览: 4721443 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

线程笔记,尽供参考[转贴]

阅读更多

贴一下我以前看线程的时候的部分笔记:

在java中,每个对象只有一个相应的monitor,一个mutex,而每一个monitor都可以有多个“doors”可以进入,即,同一个monitor中被守护的代码可以在不同的地方,因为同一个对象可以出现在不同的代码段,只要mutex锁定的对象是同一个,每个入口都用Synchronized关键字表明,当一个线程通过了Synchronized关键字,它就所住了该monitor所有的doors。因此是mutex定义了monitor而不是代码。

为了方便理解monitor的概念举个例子:
飞机山只有一个洗手间,很多乘客都想进去,但一次只能进去一个人,其他人必须等待,此时有如下对应关系:

飞机:object
乘客:各个线程
洗手间:monitor
洗手间门上的锁:mutex

因为同步的花销很大,因此要尽量避免:
1,不需要同步原子操作:一个原子操作不会被另一个线程中断,所以原子操作不需要被同步;
2,避免同步,在语言上意味着“不变性”,一个具有不变性的对象的状态在其创建之后就不会改变,因此不变的对象不需要同步;通常频繁的访问一个对象,而不修改它,那么该对象就不需要同步,好的方法是使该对象为不可变的;
3,使用同步包装器,用装饰模式可以在同步与不同步之间选择。

另,java规范中并没有要求wait()方法要作为原子操作实现的,因此,判断是否wait()的条件用while比if要好,因为if虽然在某些java实现中起作用,但是其行为实际是不明确的,用while条件也称spin lock,用其代替if只是为了保险起见。(关于这一点while和if偶理解的不是太明白)

要理解同步的本质,就要明白操作系统是如何执行程序的。对于进程和线程,操作系统设计者的目的是从概念上简化编程模型,使编程显得更自然,更符合思维习惯。操作系统设计者为使用进程和线程来编程提供了一个假设条件,即进程和线程各自的执行流是连贯的,没有任何断续执行的现象。但是实际上(以单CPU系统为例),从系统实现的底层看起来,这些进程和线程的执行流是支离破碎的,并且这些破碎的执行流片断被CPU以某种方式(即操作系统的调度程序)组合成一个串行的、混合在一起的执行流,以此推动操作系统不断运行。问题就在这里,同步问题的根源就在于看起来连贯的执行流实际上是破碎的。破碎的执行流会造成什么问题呢?比如有两个执行流A和B,A对现在需要对一个数据进行操作,但是这个操作被分割成了相连的两块执行流碎片,而另外一个执行流B本来需要在A完成这个数据操作之后才能取到这个数据然后进行它自己的计算,可是由于A对数据本应完整的操作被分割成了相连的两部分,然后CPU在A的碎片之间插入了B的取数这样一个执行流片断。这样一来,程序的行为就不符合我们原本所设想的那样,程序运行的结果就会出错。同步的本质就是让CPU不要把A的数据操作分割开,不让B有机会错误的横插一杠进来扰乱A,以保证正确的执行顺序,这样才能得到正确的我们想要的结果。不管你看起来执行得多么快的操作,都有可能被操作系统打断,从而形成碎片,导致无法预料的结果。所以,应该在需要精确时序的地方使用同步,而不是根据这个操作快不快来判断。所谓需要精确时序场合,其实就是数据的使用或操作的执行存在依赖性的地方,对于代码来说,就是完成某项操作时对参与的进程或线程执行顺序存在依赖性的代码块。

线程是一个基本问题, 有它的问题域, java中显示的实现了一部分, 隐式
的实现了一部分.
就像上文提到的mointer, mutex, 在术语上还有race condition, value condition,semaphore等
java中的Synchronized就是race condition问题,即占先问题, 其中自然
就会有mointer,mutex的概念.
wait(), notify() notifyAll()等实现了 value condition, 即去等待一个条件.
而java中要求wait(), nofity()等必须在一个Synchronized体中也是有它的
隐含意义的.
想向大家推荐一本书 thread primer, 书中虽然讲的主要是PThread, 但基本概念是介绍的相当清楚的, 能够给我们提供一个系统的且扎实的概念体系. 不知这里是否有提供上载的地方, 我可以提供. epubcn上应该也可以找到.
to mochow: 你所说的while(), if()问题, 是一个比较关键的问题.
也就是说, 从代码上看, wait()要写在while(xxx)中,而不是if(xxx)中.
"java规范中并没有要求wait()方法要作为原子操作实现的"这句话我觉得
不够明确,因为所谓的原子操作是通过获得能否获得mutex实现的, 而wait()
自然是要释放mutex的, 否则启不是只能有一个等待吗?
当有多个线程wait时,如果在另一个线程中notifyAll(),那些等待的线程就会重新去争夺mutex,这是你就会发现,如果wait是在while中的话,它在获得
mutex后还会去判断一次条件, 所以说第一个获得mutex的线程在这里应该
是通过的, 而其他的线程就会被再次wait[如果你的程序写对的话], 而如果
是在if中的话,就没有这一步.
应该说在某些场景下, 是可以写if的.[这要看你的实际需要],我们所要
讨论的是: 要知道while和if的区别在那里.
你可以想象一个生产消费问题.
一个线程生产, 多个线程消费.
消费的线程应该会有这么一段
try{
if(haveNewOne) {wait();}
}catch..
haveNewOne = false;
return 东西;
那我们想象一下如果有多个消费线程在等待,这时有一个生产线程生产
出一个东西并nodifyAll(), 则那些消费的线程就会依次从挂起状态变为运行,
然后都返回那个东西. 如果这是你希望的, 那就没有问题. 可我想大多数的
生产消费问题应该是这样的: 即生产一个消费一个, 一个东西不能被消费多次. 所以这么看来就不对了. 那我们改为while呢, 哇! 那就没有问题了.
除第一个有幸夺得mutex外得线程还要再次等待,而这才是我们所需要得.

分享到:
评论

相关推荐

    Java多线程笔记

    Java多线程笔记是 Java 编程语言中关于多线程编程的笔记,涵盖了线程基础知识、线程优先级、线程状态、守护线程、构造线程、线程中断等多方面的内容。 获取简单 main 程序中的线程 在 Java 中,可以使用 ...

    马士兵多线程笔记.zip

    以下是对马士兵多线程笔记的详细解析。 1. **多线程基础**:多线程是指一个应用程序中同时执行多个线程(即任务)的能力。这种并发执行可以提高系统资源的利用率,提升程序的响应速度和执行效率,特别是在多核...

    java多线程笔记

    Java线程的知识点总结。doc

    多线程学习笔记

    多线程学习笔记 iOS开发中,多线程是一种常见的技术手段,用于优化应用程序的性能,提升用户体验。多线程的核心是让程序能够并发地执行多个任务,合理地利用设备的计算能力,尤其是在拥有多个核心的处理器上。 ...

    进程线程笔记

    深圳华清远见学习的时候做的进程线程笔记,很有用,比较详细

    c#线程参考手册 c#线程参考手册 c#线程参考手册

    c#线程参考手册 c#线程参考手册 c#线程参考手册

    多线程笔记.md

    多线程笔记

    马士兵多线程训练营笔记

    马士兵是一位知名的IT教育专家,他的多线程训练营笔记深入浅出地讲解了这一主题,帮助开发者理解并掌握多线程的精髓。 多线程允许一个程序中有多个执行流同时运行,这样可以提高应用程序的效率和响应性。在Java中,...

    java 线程总结笔记

    花费了一上午的时候 写了一些demo。认识到四种线程池的区别。上传到csdn 供以后学习

    java多线程笔记全手打

    本笔记全面涵盖了多线程的学习,包括基础理论和实践代码,旨在帮助开发者深入理解并掌握Java多线程技术。 一、线程基础知识 线程是操作系统分配CPU时间的基本单位,一个进程中可以包含多个线程。Java通过`Thread`类...

    张孝祥Java多线程与并发库高级应用笔记

    ### 张孝祥Java多线程与并发库高级应用笔记概览 #### 一、Java多线程技术的重要性与挑战 Java线程技术是软件工程领域不可或缺的一部分,尤其在底层编程、Android应用开发以及游戏开发中,其重要性不言而喻。然而,...

    java多线程笔记分享

    java多线程笔记分享

    JAVA 多线程学习笔记

    这篇学习笔记将深入探讨Java多线程的核心概念、实现方式以及相关工具的使用。 一、多线程基础 1. 线程与进程:在操作系统中,进程是资源分配的基本单位,而线程是程序执行的基本单位。每个进程至少有一个主线程,...

    进程线程笔记.c

    进程线程笔记.c

    C#多线程笔记学习指南

    本篇笔记将深入探讨C#多线程的基本概念、操作方法以及注意事项。 首先,我们要理解多线程的基本概念。线程是程序执行的最小单位,每个线程都有自己的执行路径和栈空间,但它们共享同一块堆内存。因此,线程间的通信...

    线程笔记.xls

    多线程笔记,学习多线程的可以看看,希望对你有帮助。

    C#线程参考手册手册

    C#线程参考手册 多线程 高级编程处理

    Java多线程详解(超详细)_狂神说笔记完整版_项目代码_适合小白随课程学习

    Java多线程详解 在Java编程中,多线程是一种重要的技术,它使得程序能够同时执行多个任务,提高系统的效率和响应性。本教程将详细讲解Java中的多线程概念,包括线程的创建、状态、同步以及高级主题,旨在帮助初学者...

    java学习笔记2(多线程)

    java学习笔记2(多线程)java学习笔记2(多线程)

Global site tag (gtag.js) - Google Analytics