快速业务通道

Java多线程编程基础之非线程的方法 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-23
程赐教只能有一个线程可以执 行.

[synchornized方法]

如果一个方法声明为synchornized的,则等同于把在为个方法上调用 synchornized(this).

如果一个静态方法被声明为synchornized,则等同于把在为个方法上调用 synchornized(类.class).

现在进入wait方法和notify/notifyAll方法.这两个(或叫三个)方法都是 Object对象的方法,而不是线程对象的方法.如同锁一样,它们是在线程中调用某 一对象上执行的.

class Test{   public synchornized void test(){   //获取条件,int x 要求大于100;   if(x < 100)   wait();   }   }

这里为了说明方法没有加在try{}catch(){}中,如果没有明确在哪个对象上调 用wait()方法,则为this.wait();

假如:

Test t = new Test();

现在有两个线程都执行到t.test();方法.其中线程A获取了t的对象锁,进入 test()方法内.

这时x小于100,所以线程A进入等待.

Java多线程编程基础之非线程的方法(3)

时间:2010-12-09

当一个线程调用了wait方法后,这个线程就进入了这个对象的休息室 (waitset),这是一个虚拟的对象,但JVM中一定存在这样的一个数据结构用来记录 当前对象中有哪些程线程在等待.

当一个线程进入等待时,它就会释放锁,让其它线程来获取这个锁.

所以线程B有机会获得了线程A释放的锁,进入test()方法,如果这时x还是小于 100,线程B也进入了t的休息室.

这两个线程只能等待其它线程调用notity[All]来唤醒.

但是如果调用的是有参数的wait(time)方法,则线程A,B都会在休息室中等待 这个时间后自动唤醒.

[为什么真正的应用都是用while(条件)而不用if(条件)]

在实际的编程中我们看到大量的例子都是用?

while(x < 100)

wait();go();而不是用if,为什么呢?

在多个线程同时执行时,if(x <100)是不安全的.因为如果线程A和线程B都 在t的休息室中等待,这时另一个线程使x==100了,并调用notifyAll方法,线程A继 续执行下面的go().而它执行完成后,x有可能又小于100,比如下面的程序中调用 了--x,这时切换到线程B,线程B没有继续判断,直接执行go();就产生一个错误的 条件,只有while才能保证线程B又继续检查一次。

[notify/notifyAll方法]

这两个方法都是把某个对象上休息区内的线程唤醒,notify只能唤醒一个,但 究竟是哪一个不能确定,而notifyAll则唤醒这个对象上的休息室中所有的线 程.

一般有为了安全性,我们在绝对多数时候应该使用notifiAll(),除非你明确知 道只唤醒其中的一个线程.

那么是否是只要调用一个对象的wait()方法,当前线程就进入了这个对象的休 息室呢?事实中,要调用一个对象的wait()方法,只有当前线程获取了这个对象的 锁,换句话说一定要在这个对象的同步方法或以这个对象为参数的同步块中.

class MyThread extends Thread{   Test t = new Test();   public void run(){   t.test();   System.out.println("Thread say:Hello,World!");   }   }     public class Test {   int x = 0;   public void test(){   if(x==0)   try{   wait();   }catch(Exception e){}   }   public static void main(String[] args) throws Exception{   new MyThread().start();   }   }

这个线程就不会进入t的wait方法而直接打印出Thread say:Hello,World!.

而如果改成:

public class Test {    int x = 0;    public synchornized void test(){    if(x==0)    try{    wait();    }catch(Exception e){}    }    public static void main(String[] args) throws Exception{    new MyThread().start();    }    }

我们就可以看到线程一直等待,注意这个线程进入等待后没有 其它线程唤醒,除非强行退出JVM环境,否

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号