睫晋姬

#

几种DispatchAction的区别

  java.lang.Object

  org.apache.struts.action.Action

  org.apache.struts.actions.DispatchAction

  org.apache.struts.actions.LookupDispatchAction(Struts1.1)

  org.apache.struts.actions.EventDispatchAction(Struts1.2.9)

  org.apache.struts.actions.MappingDispatchAction(Struts1.2)

  DispatchAction

  public abstract class DispatchAction extends Action

  这是一个抽象的Action,它会根据request 中的parameter来执行相应的方法。通个这个Action类可以将不同的Action集中到一个Action文件中来。

  struts-config.xml:

  <action path="/subscription" type="org.example.SubscriptionAction" name="subscriptionForm"  scope="request" input="/subscription.jsp" parameter="method"/>

  在Action中要有相应的方法:

  public class SubscriptionAction extends DispatchAction {

  public ActionForward delete(ActionMapping mapping, ActionForm form,

  HttpServletRequest request,

  HttpServletResponse response) throws Exception {}

  public ActionForward insert(ActionMapping mapping, ActionForm form,

  HttpServletRequest request,

  HttpServletResponse response) throws Exception {}

  public ActionForward update(ActionMapping mapping, ActionForm form,

  HttpServletRequest request,

  HttpServletResponse response) throws Exception {}

  }

  然后可以通过这样的方法来访问你的程序:

  http://localhost:8080/myapp/subscription.do?method=delete

  http://localhost:8080/myapp/subscription.do?method=insert

  http://localhost:8080/myapp/subscription.do?method=update

  如果parameter中参数为空,则调用Action中的unspecified方法

  LookupDispatchAction

  public abstract class LookupDispatchAction extends DispatchAction

  通过这个Action抽象类继承DispatchAction,它的相应方法的执行由ActionMapping中parameter属性决定。每个动作实际上就是<html:submit>标签的property属性值。它适合在一个form中有很多按钮,按不同的按钮则执行不同的操作。

  struts-config.xml:

  <action path="/subscription" type="org.example.SubscriptionAction" name="subscriptionForm" scope="request"

  input="/subscription.jsp" parameter="method"/>

  ApplicationResources.properties:

  button.add=Add Record

  button.delete=Delete Record

  JSP:

  <%@ page pageEncoding="GBK"%>

  <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html"%>

  <html>

  <head>

  <title>多提交演示</title>

  </head>

  <body>

  <html:form action="subscription">

  <html:submit property="method">

  <bean:message key="button.add"/>

  </html:submit>

  <html:submit property="method">

  <bean:message key="button.delete"/>

  </html:submit>

  </html:form>

  </body>

  </html>
  在Action中必须实现getKeyMethodMap方法:

  public class SubscriptionAction extends LookupDispatchAction {

  protected Map getKeyMethodMap() {

  Map map = new HashMap();

  map.put("button.add", "add");

  map.put("button.delete", "delete");

  return map;

  }

  public ActionForward add(ActionMapping mapping,

  ActionForm form,

  HttpServletRequest request,

  HttpServletResponse response) throws Exception {}

  public ActionForward delete(ActionMapping mapping,

  ActionForm form,

  HttpServletRequest request,

  HttpServletResponse response) throws Exception {}

  }

  EventDispatchAction

  public class EventDispatchAction extends DispatchAction

  通过这个Action抽象类继承DispatchAction,它的相应方法的执行由ActionMapping中parameter属性指定多个动作,中间用逗号(,)分隔。每个动作实际上就是<html:submit>标签的property属性值。它适合在一个form中有很多按钮,按不同的按钮则执行不同的操作。

  struts-config.xml:

  (parameter中的"recalc=recalculate"意思为<html:submit>标签的property属性值为recalc调用recalculate方法,出于安全考虑能够隐藏后台的业务方法名。"defaule=save"这是可选的,没有配置property属性的<html:submit>标签干洗机将调用defaule中设置的方法名,如果defaule没有指定任何参数,则调用Action中的unspecified方法)

  <action path="/subscription" type="org.example.SubscriptionAction" name="subscriptionForm" scope="request"

  input="/subscription.jsp" parameter="save,back,recalc=recalculate,default=save"/>

  JSP:

  <%@ page pageEncoding="GBK"%>

  <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html"%>

  <html>

  <head>

  <title>多提交演示</title>

  </head>

  <body>

  <html:form action="subscription">

  <html:submit property="save" value="保存"/>

  <html:submit property="back" value="后退"/>

  <html:submit property="recalc" value="重新计算"/>

  </html:form>

  </body>

  </html>

  在Action中要有相应的方法:

  public class SubscriptionAction extends LookupDispatchAction {

  public ActionForward save(ActionMapping mapping,

  ActionForm form,

  HttpServletRequest request,

  HttpServletResponse response) throws Exception {}

  public ActionForward back(ActionMapping mapping,

  ActionForm form,

  HttpServletRequest request,

  HttpServletResponse response) throws Exception {}

  public ActionForward recalculate(ActionMapping mapping,

  ActionForm form,

  HttpServletRequest request,

  HttpServletResponse response) throws Exception {}

  }

  MappingDispatchAction

  public class MappingDispatchAction extends DispatchAction

  它的相应方法的执行由ActionMapping中parameter名决定,注意这里和LookupDispatchAction不同,LookupDispatchAction的相应方法的执行由ActionMapping中parameter属性决定。

  struts-config.xml:

  <action path="/createSubscription" type="org.example.SubscriptionAction" parameter="create">

  <forward name="success" path="/createSubscription.jsp"/>

  </action>

  <action path="/editSubscription" type="org.example.SubscriptionAction" parameter="edit">

  <forward name="success" path="/editSubscription.jsp"/>

  </action>

  <action path="/saveSubscription" type="org.example.SubscriptionAction" parameter="save"

  name="subscriptionForm" validate="true" input="/editSubscription.jsp" scope="request">

  <forward name="success" path="/savedSubscription.jsp"/>

  </action>

  <action path="/deleteSubscription" type="org.example.SubscriptionAction" name="subscriptionForm"

  scope="request" input="/subscription.jsp" parameter="delete">

  <forward name="success" path="/deletedSubscription.jsp"/>

  </action>

  <action path="/listSubscriptions" type="org.example.SubscriptionAction" parameter="list">

  <forward name="success" path="/subscriptionList.jsp"/>

  </action>

  在Action中要有相应的方法:

  public class SubscriptionAction extends MappingDispatchAction {

  public ActionForward create(ActionMapping mapping, ActionForm form,

  HttpServletRequest request,

  HttpServletResponse response) throws Exception {}

  public ActionForward edit(ActionMapping mapping, ActionForm form,

  HttpServletRequest request,

  HttpServletResponse response) throws Exception {}

  public ActionForward save(ActionMapping mapping, ActionForm form,

  HttpServletRequest request,

  HttpServletResponse response) throws Exception {}

  public ActionForward delete(ActionMapping mapping, ActionForm form,

  HttpServletRequest request,

  HttpServletResponse response) throws Exception {}

  public ActionForward list(ActionMapping mapping, ActionForm form,

  HttpServletRequest request,

  HttpServletResponse response) throws Exception {}

  }

posted @ 2009-12-05 16:59 睫晋姬 阅读(215) | 评论 (0)编辑 收藏

struts2中一个form多个提交的方法

  在很多Web应用中,为了完成不同的工作,一个HTML form标签中可能有两个或多个submit按钮,如下面的代码所示:

  <!--[if !supportLineBreakNewLine]-->

  <html action="" method="post">

  <input type="submit" value="保存" />

  <input type="submit" value="打印" />

  </html>

  由于在<form>中的多个提交按钮都向一个action提交,使用Struts2 Action的execute方法就无法判断用户点击了哪一个提交按钮。如果大家使用过Struts1.x就会知道在Struts1.2.9之前的版本需要使用一个LookupDispatchAction动作来处理含有多个submit的form。但使用LookupDispatchAction动作需要访问属性文件,还需要映射,比较麻烦。从Struts1.2.9开始,加入了一个EventDispatchAction动作。这个类可以通过java 反射来调用通过request参数指定的动作(实际上只是判断某个请求参数是不存在,如果存在,就调用在action类中和这个参数同名的方法)。使用 EventDispatchAction必须将submit的name属性指定不同的值以区分每个submit。而在Struts2中将更容易实现这个功能。

  当然,我们也可以模拟EventDispatchAction的方法通过request获得和处理参数信息。但这样比较麻烦。在Struts2中提供了另外一种方法,使得无需要配置可以在同一个action类中执行不同的方法(默认执行的是execute方法)。使用这种方式也需要通过请求参来来指定要执行的动作。请求参数名的格式为

  action!method.action

  注:由于Struts2只需要参数名,因此,参数值是什么都可以。

  下面我就给出一个实例程序来演示如何处理有多个submit的form:

  【第1步】实现主页面(more_submit.jsp)

  <%@ page language="java" import="java.util.*" pageEncoding="GBK"%>

  <%@ taglib prefix="s" uri="/struts-tags" %>

  <html>

  <head>

  <title>My JSP 'hello.jsp' starting page</title>

  </head>

  <body>

  <s:form action="submit.action" >

  <s:textfield name="msg" label="输入内容"/>

  <s:submit name="save" value="保存" align="left" method="save"/>

  <s:submit name="print" value="打印" align="left" method="print" />

  </s:form>

  </body>

  </html>

  在more_submit.jsp中有两个submit:保存和打印。其中分别通过method属性指定了要调用的方法:save和print。因此,在Action类中必须要有save和print方法。

  【第2步】实现Action类(MoreseoSubmitAction)

  package action;

  import javax.servlet.http.*;

  import com.opensymphony.xwork2.ActionSupport;

  import org.apache.struts2.interceptor.*;

  public class MoreSubmitAction extends ActionSupport implements

  ServletRequestAware {

  private String msg;

  private javax.servlet.http.HttpServletRequest request;

  // 获得HttpServletRequest对象

  public void setServletRequest(HttpServletRequest request) {

  this.request = request;

  }

  // 处理save submit按钮的动作

  public String save() throws Exception {

  request.setAttribute("result", "成功保存[" + msg + "]");

  return "save";

  }

  // 处理print submit按钮的动作

  public String print() throws Exception {

  request.setAttribute("result", "成功打印[" + msg + "]");

  return "print";

  }

  public String getMsg() {

  return msg;

  }

  public void setMsg(String msg) {

  this.msg = msg;

  }

  }

  上面的代码需要注意如下两点:

  save和print方法必须存在,否则会抛出java.lang.NoSuchMethodException异常。

  Struts2 Action动作中的方法和Struts1.x Action的execute不同,只使用Struts2 Action动作的execute方法无法访问request对象,因此,Struts2 Action类需要实现一个Struts2自带的拦截器来获得request对象,拦截器如下:

  org.apache.struts2.interceptor. ServletRequestAware

  【第3步】配置Struts2 Action

  struts.xml的代码如下:

  <?xml version="1.0" encoding="UTF-8" ?>

  <!DOCTYPE struts PUBLIC

  "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

  "http://struts.apache.org/dtds/struts-2.0.dtd">

  <struts>

  <package name="demo" extends="struts-default" >

  <action name="submit" class="action.MoreSubmitAction">

  <result name="save" >

  /result.jsp

  </result>

  <result name="print">

  /result.jsp

  </result>

  </action>

  </package>

  </struts>

  【第4步】编写结果页(result.jsp) <%@ page pageEncoding="GBK"%>

  <html>

  <head>

  <title>提交结果</title>

  </head>

  <body>

  <h1>${result}</h1>

  </body>

  </html>

  在result.jsp中将在save和print方法中写到request属性中的执行结果信息取出来,并输出到客户端。

posted @ 2009-12-05 16:34 睫晋姬 阅读(117) | 评论 (0)编辑 收藏

Struts2 标签

  用过struts1.x的人都知道,标签库有html、bean、logic、tiles,而struts2.0里的标签却没有分类,只用在jsp头文件加上

  <%@ taglib prefix="s" uri="/struts-tags" %>

  就能使用struts2.0的标签库

  A:

  <s:a href=""></s:a>-----超链接,类似于html里的<a></a>

  <s:action name=""></s:action>-----执行一个view里面的一个action

  <s:actionerror/>-----如果action的errors有值那么显示出来

  <s:actionmessage/>-----如果action的message有值那么显示出来

  <s:append></s:append>-----添加一个值到list,类似于list.add();

  <s:autocompleter></s:autocompleter>-----自动完成<s:combobox>标签的内容,这个是ajax

  B:

  <s:bean name=""></s:bean>-----类似于struts1.x中的,JavaBean的值

  C:

  <s:checkbox></s:checkbox>-----复选框

  <s:checkboxlist list=""></s:checkboxlist>-----多选框

  <s:combobox list=""></s:combobox>-----下拉框

  <s:component></s:component>-----图像符号

  D:

  <s:date/>-----获取日期格式

  <s:datetimepicker></s:datetimepicker>-----日期输入框

  <s:debug></s:debug>-----显示错误信息

  <s:div></s:div>-----表示一个块,类似于html的<div></div>

  <s:doubleselect list="" doubleName="" doubleList=""></s:doubleselect>-----双下拉框

  E:

  <s:if test=""></s:if>

  <s:elseif test=""></s:elseif>

  <s:else></s:else>-----这3个标签一起使用,表示条件判断

  F:

  <s:fielderror></s:fielderror>-----显示文件错误信息

  <s:file></s:file>-----文件上传

  <s:form action=""></s:form>-----获取相应form的值

  G:

  <s:generator separator="" val=""></s:generator>----和<s:iterator>标签一起使用

  H:

  <s:head/>-----在<head></head>里使用,表示头文件结束

  <s:hidden></s:hidden>-----隐藏值

  I:

  <s:i18n name=""></s:i18n>-----加载资源包到值堆栈

  <s:include value=""></s:include>-----包含一个输出,servlet或jsp页面

  <s:inputtransferselect list=""></s:inputtransferselect>-----获取form的一个输入

  <s:iterator></s:iterator>-----用于遍历集合

  L:

  <s:label></s:label>-----只读的标签

  M:

  <s:merge></s:merge>-----合并遍历集合出来的值

  O:

  <s:optgroup></s:optgroup>-----获取标签组

  <s:optiontransferselect doubleList="" list="" doubleName=""></s:optiontransferselect>-----左右选择框

  P:

  <s:param></s:param>-----为其他标签提供参数

  <s:password></s:password>-----密码输入框

  <s:property/>-----得到'value'的属性

  <s:push value=""></s:push>-----value的值push到栈中,从而使property标签的能够获取value的属性

  R:

  <s:radio list=""></s:radio>-----单选按钮

  <s:reset></s:reset>-----重置按钮

  S:

  <s:select list=""></s:select>-----单选框

  <s:set name=""></s:set>-----赋予变量一个特定范围内的值

  <s:sort comparator=""></s:sort>-----通过属性给list分类

  <s:submit></s:submit>-----提交按钮

  <s:subset></s:subset>-----为遍历集合输出子集

  T:

  <s:tabbedPanel id=""></s:tabbedPanel>-----表格框

  <s:table></s:table>-----表格

  <s:text name=""></s:text>-----I18n文本信息

  <s:textarea></s:textarea>-----文本域输入框

  <s:textfield></s:textfield>-----文本输入框

  <s:token></s:token>-----拦截器

  <s:tree></s:tree>-----树

  <s:treenode label=""></s:treenode>-----树的结构

  U:

  <s:updownselect list=""></s:updownselect>-----多选择框

  <s:url></s:url>-----创建url

posted @ 2009-12-05 16:01 睫晋姬 阅读(117) | 评论 (0)编辑 收藏

AJAX和XMLHTTP原理

  Ajax的原理简单来说通过XmlHttpRequest对象来向服务器发异步请求,从服务器获得数据,然后用javascript来操作DOM而更新页面。这其中最关键的一步就是从服务器获得请求数据。要清楚这个过程和原理,我们必须对 XMLHttpRequest有所了解。

  XMLHttpRequest是ajax的核心机制,它是在IE5中首先引入的,是一种支持异步请求的技术。简单的说,也就是javascript可以及时向服务器提出请求和处理响应,而不阻塞用户。达到无刷新的效果。

  所以我们先从XMLHttpRequest讲起,来看看它的工作原理。

  首先,我们先来看看XMLHttpRequest这个对象的属性。

  它的属性有:

  onreadystatechange 每次状态改变所触发事件的事件处理程序。

  responseText     从服务器进程返回数据的字符串形式。

  responseXML    从服务器进程返回的DOM兼容的文档数据对象。

  status           从服务器返回的数字代码,比如常见的404(未找到)和200(已就绪)

  status Text       伴随状态码的字符串信息

  readyState       对象状态值

  0 (未初始化) 对象已建立,但是尚未初始化(尚未调用open方法)

  1 (初始化) 对象已建立,尚未调用send方法

  2 (发送数据) send方法已调用,但是当前的状态及http头未知

  3 (数据传送中) 已接收部分数据,因为响应及http头不全,这时通过responseBody和responseText获取部分数据会出现错误,

  4 (完成) 数据接收完毕,此时可以通过通过responseXml和responseText获取完整的回应数据

  但是,由于各浏览器之间存在差异,所以创建一个XMLHttpRequest对象可能需要不同的方法。这个差异主要体现在IE和其它浏览器之间。下面是一个比较标准的创建XMLHttpRequest对象的方法。

  function CreateXmlHttp()

  {

  //非IE浏览器创建XmlHttpRequest对象

  if(window.XmlHttpRequest)

  {

  xmlhttp=new XmlHttpRequest();

  }

  //IE浏览器创建XmlHttpRequest对象

  if(window.ActiveXObject)

  {

  try

  {

  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");

  }

  catch(e)

  {

  try{

  xmlhttp=new ActiveXObject("msxml2.XMLHTTP");

  }

  catch(ex){}

  }

  }

  }
  function Ustbwuyi()

  {

  var data=document.getElementById("username").value;

  CreateXmlHttp();

  if(!xmlhttp)

  {

  alert("创建xmlhttp对象异常!");

  return false;

  }

  xmlhttp.open("POST",url,false);

  xmlhttp.onreadystatechange=function()

  {

  if(xmlhttp.readyState==4)

  {

  document.getElementById("user1").innerHTML="数据正在加载...";

  if(xmlhttp.status==200)

  {

  document.write(xmlhttp.responseText);

  }

  }

  }

  xmlhttp.send();

  }

  如上所示,函数首先检查XMLHttpRequest的整体状态并且保证它已经完成(readyStatus=4),即数据已经发送完毕。然后根据服务器的设定询问请求状态,如果一切已经就绪(status=200),那么就执行下面需要的操作。

  对于XmlHttpRequest的两个方法,open和send,其中open方法指定了:

  a、向服务器提交数据的类型,即post还是get。

  b、请求的url地址和传递的参数。

  c、传输方式,false为同步,true为异步。默认为true。如果是异步通信方式(true),客户机就不等待服务器的响应;如果是同步方式(false),客户机就要等到服务器返回消息后才去执行其他操作。我们需要根据网站优化实际需要来指定同步方式,在某些页面中,可能会发出多个请求,甚至是有组织有计划有队形大规模的高强度的request,而后一个是会覆盖前一个的,这个时候当然要指定同步方式。

  Send方法用来发送请求。

  知道了XMLHttpRequest的工作流程,我们可以看出,XMLHttpRequest是完全用来向服务器发出一个请求的,它的作用也局限于此,但它的作用是整个ajax实现的关键,因为ajax无非是两个过程,发出请求和响应请求。并且它完全是一种客户端的技术。而XMLHttpRequest正是处理了服务器端和客户端通信的问题所以才会如此的重要。

  现在,我们对ajax的原理大概可以有一个了解了。我们可以把服务器端看成一个数据接口,它返回的是一个纯文本流,当然,这个文本流可以是XML格式,可以是Html,可以是Javascript代码,也可以只是一个字符串。这时候,XMLHttpRequest向服务器端请求这个页面,服务器端将文本的结果写入页面,这和普通的web开发流程是一样的,不同的是,客户端在异步获取这个结果后,不是直接显示在页面,而是先由javascript来处理,然后再显示在页面。至于现在流行的很多ajax控件,比如magicajax等,可以返回DataSet等其它数据类型,只是将这个过程封装了的结果,本质上他们并没有什么太大的区别。

posted @ 2009-12-05 15:54 睫晋姬 阅读(121) | 评论 (0)编辑 收藏

Java线程:线程的同步-同步方法

    线程的同步是保证多线程安全访问竞争资源的一种手段。

    线程的同步是Java多线程编程的难点,往往开发者搞不清楚什么是竞争资源、什么时候需要考虑同步,怎么同步等等问题,当然,这些问题没有很明确的答案,但有些原则问题需要考虑,是否有竞争资源被同时改动的问题?
 
    在本文之前,请参阅《Java线程:线程的同步与锁》,本文是在此基础上所写的。
 
    对于同步,在具体的Java代码中需要完成一下两个操作:

    把竞争访问的资源标识为private;

    同步哪些修改变量的代码,使用synchronized关键字同步方法或代码。

    当然这不是唯一控制并发安全的途径。
 
    synchronized关键字使用说明

    synchronized只能标记非抽象的方法,不能标识成员变量。
 
    为了演示同步方法的使用,构建了一个信用卡账户,起初信用额为100w,然后模拟透支、存款等多个操作。显然银行账户User对象是个竞争资源,而多个并发操作的是账户方法oper(int x),当然应该在此方法上加上同步,并将账户的余额设为私有变量,禁止直接访问。
 
 
/**
* Java线程:线程的同步
*
* @author leizhimin 2009-11-4 11:23:32
*/
public class Test {
        public static void main(String[] args) {
                User u = new User("张三", 100);
                MyThread t1 = new MyThread("线程A", u, 20);
                MyThread t2 = new MyThread("线程B", u, -60);
                MyThread t3 = new MyThread("线程C", u, -80);
                MyThread t4 = new MyThread("线程D", u, -30);
                MyThread t5 = new MyThread("线程E", u, 32);
                MyThread t6 = new MyThread("线程F", u, 21);

                t1.start();
                t2.start();
                t3.start();
                t4.start();
                t5.start();
                t6.start();
        }
}

class MyThread extends Thread {
        private User u;
        private int y = 0;

        MyThread(String name, User u, int y) {
                super(name);
                this.u = u;
                this.y = y;
        }

        public void run() {
                u.oper(y);
        }
}

class User {
        private String code;
        private int cash;

        User(String code, int cash) {
                this.code = code;
                this.cash = cash;
        }

        public String getCode() {
                return code;
        }

        public void setCode(String code) {
                this.code = code;
        }

        /**
         * 业务方法
         * @param x 添加x万元
         */
        public synchronized void oper(int x) {
                try {
                        Thread.sleep(10L);
                        this.cash += x;
                        System.out.println(Thread.currentThread().getName() + "运行结束,增加“" + x + "”,当前用户账户余额为:" + cash);
                        Thread.sleep(10L);
                } catch (InterruptedException e) {
                        e.printStackTrace();
                }
        }

        @Override
        public String toString() {
                return "User{" +
                                "code='" + code + '\'' +
                                ", cash=" + cash +
                                '}';
        }
}
 
    输出结果:

线程A运行结束,增加“20”,当前用户账户余额为:120
线程F运行结束,增加“21”,当前用户账户余额为:141
线程E运行结束,增加“32”,当前用户账户余额为:173
线程C运行结束,增加“-80”,当前用户账户余额为:93
线程B运行结束,增加“-60”,当前用户账户余额为:33
线程D运行结束,增加“-30”,当前用户账户余额为:3

Process finished with exit code 0
 
    反面教材,不同步的情况,也就是去掉oper(int x)方法的synchronized修饰符,然后运行程序,结果如下:

线程A运行结束,增加“20”,当前用户账户余额为:61
线程D运行结束,增加“-30”,当前用户账户余额为:63
线程B运行结束,增加“-60”,当前用户账户余额为:3
线程F运行结束,增加“21”,当前用户账户余额为:61
线程E运行结束,增加“32”,当前用户账户余额为:93
线程C运行结束,增加“-80”,当前用户账户余额为:61

Process finished with exit code 0
 
    很显然,上面的结果是错误的,导致错误的原因是多个线程并发访问了竞争资源u,并对u的属性做了改动。
 
    可见同步的重要性。
 
    注意:

    通过前文可知,线程退出同步方法时将释放掉方法所属对象的锁,但还应该注意的是,同步方法中还可以使用特定的方法对线程进行调度。这些方法来自于java.lang.Object类。
 
void notify()   
                    唤醒在此对象监视器上等待的单个线程。   
void notifyAll()   
                    唤醒在此对象监视器上等待的所有线程。   
void wait()   
                    导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法。   
void wait(long timeout)   
                    导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量。   
void wait(long timeout, int nanos)   
                    导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量。
 
    结合以上方法,处理多线程同步与互斥问题非常重要,著名的生产者-消费者例子就是一个经典的例子,任何语言多线程必学的例子。

posted @ 2009-12-05 15:50 睫晋姬 阅读(122) | 评论 (0)编辑 收藏

仅列出标题
共3页: 上一页 1 2 3