??xml version="1.0" encoding="utf-8" standalone="yes"?>污视频在线观看网站,久久精品视频免费观看,亚洲а∨精品天堂在线http://www.aygfsteel.com/mulinka/category/1841.htmlt实肯干Q不可眼高手?/description>zh-cnWed, 28 Feb 2007 13:15:05 GMTWed, 28 Feb 2007 13:15:05 GMT60在JavaE序中运行外部类文gQ{Q?/title><link>http://www.aygfsteel.com/mulinka/articles/11427.html</link><dc:creator>之卡卡</dc:creator><author>之卡卡</author><pubDate>Mon, 29 Aug 2005 05:03:00 GMT</pubDate><guid>http://www.aygfsteel.com/mulinka/articles/11427.html</guid><wfw:comment>http://www.aygfsteel.com/mulinka/comments/11427.html</wfw:comment><comments>http://www.aygfsteel.com/mulinka/articles/11427.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/mulinka/comments/commentRss/11427.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/mulinka/services/trackbacks/11427.html</trackback:ping><description><![CDATA[<TABLE width="100%"> <TBODY> <TR> <TD class=a14><B>一、引a</B></TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>无论是用传统的编E语aQC++、VB{)q是Java语言~程Q都l常需要在一个运行的E序中执行另外一个独立的外部E序。例如用Java设计一个IDEE序Q那么这个IDEE序必需能够调式、运行其它独立的外部JavaE序。况且直接运行已l存在的外部E序来实现本E序的某些特定的功能Q也是提高程序开发效率的一U重要手Dc?/TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>Java2为实现在一个JavaE序中运行外部类文gQ即JavaE序Q提供了的两U解x案,卛_同一q程中运行外部类文g和在不同q程中运行外部类文g?/TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14><B>二、在同一q程中运行外部类文g</B></TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>Java规定MJava应用QapplicationQ的入口都是Qmain()Q因此要实现在同一q程中运行外部类文gQ只要想办法在程序中直接调用外部cL件的main()Ҏ卛_?/TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>Java2中的映象QReflectionQAPI可以对Java虚拟Z的类、接口、对象等q行映象Q通过它能够动态地得到cR接口、对象的各种信息Q还能够动态地讄对象的域的|q可以动态地调用对象中的各种Ҏ?/TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>因此Q我们可以利用Reflection API在运行时QruntimeQ动态地定外部cL件的main()ҎQ然后调用它。例如:</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>假定被执行的外部类文gQInvoked.javaQ如下:</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>public class Invoked {</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>public static void main(String[] args) {</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>if (args.length != 2) {</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>System.err.println("Usage: java Invoked name sex ");</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>System.exit(1);</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>}</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>System.out.println("Hello, I come from OutClassFile!");</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>System.out.println("my name is "+args[0]);</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>System.out.println("my sex is "+args[1]);</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>}</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>}</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>q行上述cL件的ȝ序(Invoker.javaQ一般具有如下Ş式:</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>import java.lang.reflect.*;</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>public class Invoker {</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>public static void main(String[] args) {</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>//args[0]存储被执行的外部cdQ本例中args[0]=“Invoked?/TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>if (args.length != 1) {</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>System.err.println("Usage: java Invoker ");</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>System.exit(1);</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>}</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>Class[] argTypes = new Class[1]; </TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>argTypes[0] = String[].class;</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>try {</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>Method mainMethod = Class.forName(args[0]).getDeclaredMethod("main",argTypes);</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>Object[] argListForInvokedMain = new Object[1];</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>//被调用的main()Ҏ的参C?1</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>argListForInvokedMain[0] = new String[2];</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>//被调用的main()Ҏ的参数是一个长度ؓ2的String数组</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>String argsToinvoked[]={"WangShuangLin","Man"};</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>ArgListForInvokedMain[0]= argsToinvoked;</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>//讄传递给被调用的外部cȝmain()Ҏ的参?/TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>mainMethod.invoke(null, argListForInvokedMain);</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>//inkoke(Object obj, Object[] args)是调用方法;</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>//其中obj是方法所在的对象实例; 但因里的main()是静态方法,</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>//所以无d例化Q填上null卛_Q?/TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>//args是传递给该方法的参数?/TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>}</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>catch (ClassNotFoundException ex) {</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>System.err.println("Class"+args[0]+"not found in classpath.");</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>}</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>catch (NoSuchMethodException ex) {</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>System.err.println("Class "+args[0]+" does not define public static void main(String[])");</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>}</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>catch (InvocationTargetException ex) {</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>System.err.println("Exception while executing "+args[0]+ ":"+ex.getTargetException());</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>}</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>catch (IllegalAccessException ex) {</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>System.err.println("main(String[]) in class "+args[0] + "is not public");</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>}</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>}</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>}</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>用如下的命o行运行主E序Qjava Invoker Invoked?/TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>q个例子单展CZ如何在同一q程QprocessQ中执行外部cLӞ不仅如此Q而且q是在同一U程QthreadQ中Q当然完全可以在不同的线E中来完成?/TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14><B>三、在不同q程中运行外部类文g</B></TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>要在不同q程中运行外部类文gQ只要想办法在程序中直接执行Q?/TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>java 外部cL?Q本例即为:java InvokedQ即可?/TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>q运的是java.lang.Runtime cL供了exce()Ҏ来完成对外部可执行程序的调用。注意:在这里exce()Ҏ调用的其实是java解释器这个可执行E序Q外部类文gInvoked.class只不q是作ؓjava解释器的参数出现。事实上Qexce()Ҏq可以直接调用其它的可执行文Ӟ而不仅仅是java解释器?/TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>假定被执行的外部类文g仍然是上面的Invoked.javaQ?/TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>那么q行上述cL件的ȝ序(InvokerFromSeparateProcess.javaQ如下:</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>public class InvokerFromSeparateProcess {</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>public static void main(String[] args) {</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>if (args.length != 1) {</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>System.err.println("Usage: java InvokerFromSeparateProcess ");</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>System.exit(1);</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>}</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>String name=?WangShuangLin?</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>String sex=?man?</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>try {</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>Process p = Runtime.getRuntime().exec("java "+args[0]+name+sex);</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>}</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>catch (java.io.IOException ex) {</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>System.err.println("Problems invoking class "+args[0]+": "+ex);</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>}</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>}</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>}</TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>用如下的命o行运行主E序Qjava InvokerFromSeparateProcess Invoked?/TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>你也怼发现q没有看到被调用的外部类文gInvoked.class的输出。问题在于新q程Qnew porcessQ的标准输出(standard output streamQƈ不会自动地定向到stdout。ؓ了得到ƈ昄新进E的输出信息Q我们可以利用p.getInputStream()来读取新q程的输Z息,然后把读到的信息发送到标准输出(standard outputQ上?/TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14><B>四、结?/B></TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>利用Java2中的映象QReflectionQAPI实现在同一q程QprocessQ中执行外部cL件的ҎQ优Ҏ消耗资源较,因ؓ它不打开新的q程Q功能强大,因ؓ它不但可以执行外部类文g的main()ҎQ而且q可以执行外部类文g的其它方法,可以非常l致地利用外部类文g的一切资源。缺Ҏ它只能执行用Java~写的外部类文gQ而不能执行其它Ş式的可执行文Ӟ如EXE、COM{;其次是编E较W二UŞ式稍微复杂一炏V?/TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>利用java.lang.Runtime cL供了exce()Ҏ来完成对外部可执行程序的调用的方法,优点是编E简单,q且可以q行一切可执行E序Q包括用其它语言~写的程序。缺Ҏ消耗资源较多,因ؓ它要打开新的q程Q其ơ是它只能整体运行外部类文gQ而不能细致地讉K被调用程序的内部资源?/TD></TR></TBODY></TABLE> <TABLE width="100%"> <TBODY> <TR> <TD class=a14>一般情况下Q如果要q行用Java~写的外部类文gQ选择W一U方法较为灵zR恰当;如果要运行用其它语言~写的可执行E序Q选择W二U方法较为方ѝ直接,但是一般情况下要尽量避免这样做Q否则将降低JavaE序的跨q_性,因ؓq种外部E序一般是q_相关的?/TD></TR></TBODY></TABLE><img src ="http://www.aygfsteel.com/mulinka/aggbug/11427.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/mulinka/" target="_blank">之卡卡</a> 2005-08-29 13:03 <a href="http://www.aygfsteel.com/mulinka/articles/11427.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Dynamic proxyQ动态代理模式)http://www.aygfsteel.com/mulinka/articles/8724.html之卡卡之卡卡Fri, 29 Jul 2005 03:10:00 GMThttp://www.aygfsteel.com/mulinka/articles/8724.htmlhttp://www.aygfsteel.com/mulinka/comments/8724.htmlhttp://www.aygfsteel.com/mulinka/articles/8724.html#Feedback0http://www.aygfsteel.com/mulinka/comments/commentRss/8724.htmlhttp://www.aygfsteel.com/mulinka/services/trackbacks/8724.html
使用动态代理,你创建的包装器类不要求ؓ所有方法都使用昑ּ的包装器Q创建的子类也不要求h严格的出w,两者方法可任选一U你认ؓ最好的。但是,动态代理仍然有一个限制。当你用动态代理时Q要包装/扩展的对象必dC个接口,该接口定义了准备在包装器中用的所有方法。这一限制的宗旨是鼓励良好的设计,而不是ؓ你带来更多的ȝ。根据经验,每个c都臛_应该实现一个接口(nonconstant接口Q。良好的接口用法不仅使动态代理成为可能,q有利于E序的模块化?BR>
2U写invoke()
注意:必须有return method.invoke(wrapped, args)

以下内容为程序代?

 public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        Class[] paramTypes = method.getParameterTypes();
        for (int i=0; i < paramTypes.length; i++) {
            if (Tool.class.isAssignableFrom(paramTypes[i])) {
                args[i] = Tool.RATCHET;
            }
        }
        return method.invoke(wrapped, args);
    }

  public Object invoke(Object proxy, Method m, Object[] args)
           throws Throwable {
       Object result;
       try {
           System.out.println("before method " + m.getName());
           result = m.invoke(obj, args);
       } catch (InvocationTargetException e) {
           throw e.getTargetException();
       } catch (Exception e) {
           throw new RuntimeException("unexpected invocation exception: "
                  + e.getMessage());
       } finally {
           System.out.println("after method " + m.getName());
       }
       return result;
    }
}


q行效果如下Q?BR>before method bar
after method bar


dynamic proxy的实战步?BR>实际上dynamic proxy只有关键以下几个东西
一、业务接口:一个Interface
二、实C务接口的c:一个承Interface的Class
三、自己写一个承了java.lang.reflect.InvocationHandler的Handlerc?BR>四、在q个HandlercM实现invokeQ)Ҏ
五、在invokeQ)Ҏ中一定要记得写return method.invoke(wrapped, args)
六、要使Handler和自q业务接口兌q的写下面的代码Q一般写在HandlercMQ?BR>
以下内容为程序代?

    public static Object newInstance(Object obj) {
       return java.lang.reflect.Proxy.newProxyInstance(obj.getClass()
              .getClassLoader(), obj.getClass().getInterfaces(),new Handler(obj));
    }

q样q回的就是经q代理的对象了(把原对象和Handlerl定CP

dynamic proxy的典型应用《用JAVA中的动态代理实现数据库q接池?BR>
dynamic proxy在JDBC上的应用
IBM文章:
《用JAVA中的动态代理实现数据库q接池?/A>

之卡卡 2005-07-29 11:10 发表评论
]]>
Java中ThreadLocal的设计与使用http://www.aygfsteel.com/mulinka/articles/7377.html之卡卡之卡卡Fri, 08 Jul 2005 08:54:00 GMThttp://www.aygfsteel.com/mulinka/articles/7377.htmlhttp://www.aygfsteel.com/mulinka/comments/7377.htmlhttp://www.aygfsteel.com/mulinka/articles/7377.html#Feedback0http://www.aygfsteel.com/mulinka/comments/commentRss/7377.htmlhttp://www.aygfsteel.com/mulinka/services/trackbacks/7377.htmlJava中ThreadLocal的设计与使用
原文出处Q?A title=原文出处 >http://www.huawei.org.cn/news/article_show.asp?id=27413

 
  早在Java 1.2推出之时QJavaq_中就引入了一个新的支持:java.lang.ThreadLocalQ给我们在编写多U程E序时提供了一U新的选择。用这个工L可以很简z地~写Z的多线E程序,虽然ThreadLocal非常有用Q但是似乎现在了解它、用它的朋友还不多?BR>  
  ThreadLocal是什?/STRONG>

  ThreadLocal是什么呢Q其实ThreadLocalq是一个线E的本地实现版本Q它q不是一个ThreadQ而是thread local variableQ线E局部变量)。也许把它命名ؓThreadLocalVar更加合适。线E局部变量(ThreadLocalQ其实的功用非常单,是为每一个用该变量的线E都提供一个变量值的副本Q是每一个线E都可以独立地改变自q副本Q而不会和其它U程的副本冲H。从U程的角度看Q就好像每一个线E都完全拥有该变量。线E局部变量ƈ不是Java的新发明Q在其它的一些语a~译器实玎ͼ如IBM XL FORTRANQ中Q它在语a的层ơ提供了直接的支持。因为Java中没有提供在语言层次的直接支持,而是提供了一个ThreadLocal的类来提供支持,所以,在Java中编写线E局部变量的代码相对比较W拙Q这也许是线E局部变量没有在Java中得到很好的普及的一个原因吧?BR>  
  ThreadLocal的设?BR>  
  首先看看ThreadLocal的接口:
  
  Object get() ; // q回当前U程的线E局部变量副?protected Object initialValue(); // q回该线E局部变量的当前U程的初始?BR>  void set(Object value); // 讄当前U程的线E局部变量副本的?BR>  
  ThreadLocal?个方法,其中值得注意的是initialValue()Q该Ҏ是一个protected的方法,昄是ؓ了子c重写而特意实现的。该Ҏq回当前U程在该U程局部变量的初始|q个Ҏ是一个gq调用方法,在一个线E第1ơ调用get()或者set(Object)时才执行Qƈ且仅执行1ơ。ThreadLocal中的实实现直接q回一个nullQ?BR>  
  
protected Object initialValue() { return null; }
  
  ThreadLocal是如何做Cؓ每一个线E维护变量的副本的呢Q其实实现的思\很简单,在ThreadLocalcM有一个MapQ用于存储每一个线E的变量的副本。比如下面的CZ实现Q?BR>  
  
public class ThreadLocal
  {
  private Map values = Collections.synchronizedMap(new HashMap());
  public Object get()
  {
  Thread curThread = Thread.currentThread();
  Object o = values.get(curThread);
  if (o == null && !values.containsKey(curThread))
  {
  o = initialValue();
  values.put(curThread, o);
  }
  return o;
  }
  
  public void set(Object newValue)
  {
  values.put(Thread.currentThread(), newValue);
  }
  
  public Object initialValue()
  {
  return null;
  }
  }
  
  当然Q这q不是一个工业强度的实现Q但JDK中的ThreadLocal的实现M思\也类g此?BR>  
  ThreadLocal的?BR>  
  如果希望U程局部变量初始化其它|那么需要自己实现ThreadLocal的子cdƈ重写该方法,通常使用一个内部匿名类对ThreadLocalq行子类化,比如下面的例子,SerialNumcMؓ每一个类分配一个序P
  
  
public class SerialNum
  {
  // The next serial number to be assigned
  
  private static int nextSerialNum = 0;
  private static ThreadLocal serialNum = new ThreadLocal()
  {
  protected synchronized Object initialValue()
  {
  return new Integer(nextSerialNum++);
  }
  };
  
  public static int get()
  {
  return ((Integer) (serialNum.get())).intValue();
  }
  }
  
  SerialNumcȝ使用非常地单,因ؓget()Ҏ是static的,所以在需要获取当前线E的序号Ӟ单地调用Q?BR>  
 
 int serial = SerialNum.get();
  
  卛_?BR>  
  在线E是zd的ƈ且ThreadLocal对象是可讉K的时Q该U程持有一个到该线E局部变量副本的隐含引用Q当该线E运行结束后Q该U程拥有的所以线E局部变量的副本都将失效Qƈ{待垃圾攉器收集?BR>  
  ThreadLocal与其它同步机制的比较
  ThreadLocal和其它同步机制相比有什么优势呢QThreadLocal和其它所有的同步机制都是Z解决多线E中的对同一变量的访问冲H,在普通的同步机制中,是通过对象加锁来实现多个线E对同一变量的安全访问的。这时该变量是多个线E共享的Q用这U同步机刉要很l致地分析在什么时候对变量q行dQ什么时候需要锁定某个对象,什么时候释放该对象的锁{等很多。所有这些都是因为多个线E共享了资源造成的。ThreadLocal׃另一个角度来解决多线E的q发讉KQThreadLocal会ؓ每一个线E维护一个和该线E绑定的变量的副本,从而隔M多个U程的数据,每一个线E都拥有自己的变量副本,从而也没有必要对该变量进行同步了。ThreadLocal提供了线E安全的׃n对象Q在~写多线E代码时Q可以把不安全的整个变量装qThreadLocalQ或者把该对象的特定于线E的状态封装进ThreadLocal?BR>  
  ׃ThreadLocal中可以持有Q何类型的对象Q所以用ThreadLocal get当前U程的值是需要进行强制类型{换。但随着新的Java版本Q?.5Q将模版的引入,新的支持模版参数的ThreadLocalcd从中受益。也可以减少强制cd转换Qƈ一些错误检查提前到了编译期Q将一定程度地化ThreadLocal的用?BR>  
  ȝ
  当然ThreadLocalq不能替代同步机Ӟ两者面向的问题领域不同。同步机制是Z同步多个U程对相同资源的q发讉KQ是Z多个U程之间q行通信的有效方式;而ThreadLocal是隔d个线E的数据׃nQ从Ҏ上就不在多个U程之间׃n资源Q变量)Q这样当然不需要对多个U程q行同步了。所以,如果你需要进行多个线E之间进行通信Q则使用同步机制Q如果需要隔d个线E之间的׃n冲突Q可以用ThreadLocalQ这极大地化你的程序,使程序更加易诅R简z?nbsp;


之卡卡 2005-07-08 16:54 发表评论
]]>
վ֩ģ壺 °Ͷ| | | | | ޶| | | Ӫɽ| | ʯ| | | ػʵ| Ӷ| ʯ| | | «Ϫ| | ½| | | ٷ| | | ޳| | ɽ| | | | | ͭ| ɽ| | | ǰ| Զ| | Ӫ|