诗剑书生的专栏

我在灌江口上住,花开花落,不知流年度.雁过空遗秋色暮,抚琴细听梧桐雨. 轻舞残虹漫展书,云卷云舒,思愫万千缕.安得婵娟与共处,长作识字耕田夫.                   诗剑书生 于灌江口.听潮居

用户操作
[即时聊天] [发私信] [加为好友]
诗剑书生ID:axman
114134次访问,排名809,好友33人,关注者39人。
一个男人. 一个写程序男人. 一个写程序并从程序中寻找快乐的男人. 一个写程序并从程序中寻找快乐又把快乐传递给大家的男人.
一个书生. 一个寂寞的书生. 一个寂寞的梅香竹影下敲声写韵的书生. 一个寂寞的梅香竹影下敲声写韵晨钟暮鼓中逸气扬剑的书生.
那个男人是位书生。没有人知道他的姓名,居无定所,行无定踪,亦耕亦读,或渔或樵。
axman的文章
原创 89 篇
翻译 0 篇
转载 0 篇
评论 174 篇
axman的公告
最近评论
axman:这个组件经过N年检验没有任何问题,你的调用方式错误。只从form.getCsvPath()这几个字符我就可以判断你一定是使用了某种框架,先处理了request对象.

如果真正了解sevlet底层的人,request一经处理过滤,除非pushback,否则不可能再次读出原来的数据.这是最最起码的常识.
zhoche2008:Upload up = new Upload();
up.init(request);
up.setSaveDir(form.getCsvPath());
up.setTagFileName(fileName);
up.uploadFile();
String pathName = up.getFileName()[0];
按你的……
YuLimin:也只有axman老大才会如何深刻地描述并分享这种技术的根源,憾动ing!
hujianshi:喜欢看您的文章,支持!!!!
xiaozhang927:一个有心人.
文章分类
收藏
    相册
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 多线程编程的设计模式 临界区模式(三) 收藏

    新一篇: symbian的清除栈 | 旧一篇:  多线程编程的设计模式 临界区模式(二)

    [高级主题:关于synchronized]

    其实在多线程编程基础部分,我已经谈过synchronized相关的内容.但临界区模式是其它多线程编程模式的基
    础,所以在这里继续深入一下谈谈synchronized相关的一些内容.

    只要见到synchronized关键字,第一要想到的问题就是,synchronized在保护谁?

    在上面的例子中,synchronized保护的是Corrie对象的counter,name,number三个字段不被"交差赋值",也就是
    这三个字段同时只能被一个线程访问.
    其次我们要考虑的问题是:这些对象都被妥善地保护了吗?

    这是非常重要的问题.无论你花巨资打造一把高安全性锁,把自己的家门牢牢地锁住,可是你却把门旁边的窗子
    敞开着,那么你花巨资打造的锁又要什么意义呢?所以要确保从任何一个通道访问被保护的对象都被加锁控制
    的,比如字段是否都private或protected的,对于protected的子类中的扩展方法是否能保护被保护对象.

    对于上面的例子因为display有可能被外面的方法单独调用,所以它也必须是同步的.而test方法只会在into中
    调用,简单说它只是所有通道被加了锁的大房子中的一个小单元,所以不必担心有人会从外部访问它.

    要注意保护的范围是三个同时需要保护的字段,如果它们被分别放在synchronized方法中保护,并不能保证它们
    本个字段同时只有一个线程访问.

    那么我们就有一个问题,获取谁的锁呢?

    要保护一个对象,当然直接获取这个对象的锁,我们上面的例子可以理解为要同时保护三个对象,那么其实就是
    要保护这个本个对象的容器.也就是它们所在的实例.如果不相关的三个对象要同时保护,一定要放在同时容纳
    它们的容器中,否则无法同时保护它们的状态.对于上面的例子我们同样可以理解为要保护的是Corrie的实例,
    因为这个实例是这三个字段的容器.所以我们用synchronized方法就是等同于synchronized(this){.......}
    如果这个游戏中有多个山洞,而只有一块显示牌,那以我们就需要保护多个实例的三个字段同时只被一个线程
    访问,我们就需要synchronized(Corrie.class)来保证多个实例被多个线程访问时只有一个对程能同时对三个
    字段访问.
    所以获取谁的锁定也是一个很重要的问题,如果你选择了错误的对象,就象你花巨资打了一把锁却锁了别人的
    门.

    synchronized就是原子操作,简单说在一个线程进行同步块中的代码时不能进入,这是很明显的.但同时,多个
    同步方法或多个获取同一对象的同步块在同一时候也只能一个线程能访问其中之一,因为控制谁能访问的是要
    获得那个同步对象的锁.如:
    class C{
     synchronized  a(){}
     synchronized  b(){}
    }

    当一个线程进入同步方法a后那么其它线程当然不能进入a,同时也不能进入b,因为能进入的条件是获取this对
    象的锁.一个结程进入a后this对象的锁被这个线程获取,其它线程进入b也同样要获取这个锁,而不仅仅是进入
    a要获取这个锁.这一点一定要理解.

    理解上面的知识我们再回过头来看原子操作.

    JLS规定对于基本类型(除long和double)以外的赋值和引用都是原子操作,并且对于引用类型的赋值和引用也是
    原子操作.

    注意这里有两个方面的知识点:

    1.对于long和double的操作非原子性的.需要说明这只是JLS的规定,但大多数JVM的实现其实已经保证了long和
    double的赋值和引用也是原子性的,只是允许某种实现可以不是原子性的操作.

    对于其它基本类型如int,如果一个线程执行x = 1;另一个线程执行x = 2;
    由于可见性的问题(多线程编程系统中已经介绍),x要么就是1,要么就是2,看谁先同步到主存储区.

    但对于long,l = 1;l = 2;分别由两个线程执行的结果有可能不是你想象的,它们有可能是0,或1,或2,或一个其
    它的随机数,简单说两上线程中l的值的部分bit位可能被另一个线程改写.所以最可靠的是放在synchronized中
    或用volatile 保护.当然这里说的是"有非常可靠的需要",一般而言现在的JVM已经能保证long和double也是原
    子操作的.

    2.我们看到,对于引用对象的赋值和引用也是原子的.

    我们还是看javaworld上dcl的例子.

     那个错误的例子误了好多人,(JAVA与模式的作者就是受害人),我们先不说JAVA内存模型的原因(前面我已经从
    JAVA内存模型上说明了那个例子是错误的,我是说对那个例子的分析是错误的).单从对于"引用对象的赋值和引
    用也是原子的"这句话,就知道对于引用字段的赋值,绝对不可能出现先分配空间,然后再还没有被始化或还没有
    调构造方法之前又被别的线程引用.因为当一个线程在执行赋值的时候是原子性的操作,其它线程的引用操作也是原子性的操作 的,在赋值操作没有完成之前其它线程根本不可能见到"分配了空间却没有
    初始化或没有调用构造方法"的这个对象.

    不知道什么原因,这样的一个例子从它诞生开始竟然是所有人都相信了,也许有人责疑过但我不知道.如果你有足
    够的基础知识,就不必跟着别人的感觉走!

    因为这是一个最最基础的模式,暂时不介绍它与其它模式的关系.在以后介绍其它模式时反过来再和它进行比较.

    而一些复杂的模式都是在这个简单的模式的基础上延伸的.

     

     

     

    发表于 @ 2006年09月07日 12:18:00|评论(loading...)|编辑

    新一篇: symbian的清除栈 | 旧一篇:  多线程编程的设计模式 临界区模式(二)

    评论

    #坎井之蛙  发表于2006-10-24 11:45:00  IP: 61.139.69.*
    非常好的系列文章,收藏 学习 +敬仰!呵!期待更多的好文章!
    发表评论  


    当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
    Csdn Blog version 3.1a
    Copyright © axman