不好意思, 没写完。我觉得这样用sleep等在那里,好像实在占用系统资源多。  请问我怎么样让这个类的put()韩树被调用一次后, 自动激活get()函数继续运行下去?  请问可以做到吗? wait()和notify()这样的函数在这里用的上吗?

解决方案 »

  1.   

    可以呀!你做一个事件队列类:private int size = 0;
    private int capacity;
    public synchronized boolean isFull() {  
     return ( size == capacity );  
     } 
     
    public synchronized void add(Object obj) throws InterruptedException {  
     
     while ( isFull() ) {  
     wait();  
     }  
     
     queue[head] = obj;  
     head = ( head + 1 ) % capacity;  
     size++; 
     notifyAll(); // let any waiting threads know about change  
     }  
     
     public synchronized Object remove() throws InterruptedException {  
     while ( size == 0 ) {  
     wait();  
     }  
     Object obj = queue[tail];  
     queue[tail] = null; // don’t block GC by keeping reference  
     tail = ( tail + 1 ) % capacity;  
     size—;  
     
     
            notifyAll(); // let any waiting threads know about change  
     
             return obj;  
     
         } 
     
      

  2.   

    你那里就不能用sleep(),sleep()函数调用时是不会释放资源的。
      

  3.   

    我想问一下  你在 remove() 和 add()函数的定义中都加入了synchronized,  那万一我在运行remove()时候, 发现为空, 不在运行, 结果add()也不能运行,岂不是有问题?
    还有,  这个类要从Thread继承出来吗?  那run()函数就这么空着也可以阿!?
      

  4.   

    还是帮我看一下我的代码有什么错吧好不好?public class Queue extends Thread{
      private LinkedList list = new LinkedList();  public Queue() {
      }  public synchronized void put(Object v){
        list.addFirst(v);
        this.notify();
      }  public Object get(){
        while (true){
                synchronized(this){
                        if ( !isEmpty() )
                                return list.removeLast();
                }
                try{
                    wait();
                }catch(Exception e){
                    System.err.println(e.toString());
                }
        }
      }  public boolean isEmpty(){
        return list.isEmpty();
      }  //for debug
      public static void main(String[] args) {
        Queue queue1 = new Queue();    for(int i=0;i<10;i++)
          queue1.put(Integer.toString(i));    while(!queue1.isEmpty())
          System.out.println(queue1.get());
      }
    }
      

  5.   

    wait()函数与Sleep函数的区别就是wait()是会使线程释放资源的。不会出现死锁。
      

  6.   

    这个类不需要从Thread派生出来呀!他仅仅是一个队列呀!
      

  7.   

    可是我把这个声明去掉以后还是报错:java.lang.IllegalMoniterStateException: current thread not owner  
    而且书上也说不可以在非线程类中使用wait()函数的嘛,虽然这是object的最近本的方法
      

  8.   

    而且我不明白这个notifyAll()方法的范围是什么?
      

  9.   

    这是一个先进先出队列!你先看看。不懂再问!
    public class SimpleObjectFIFO extends Object {
    private Object[] queue;
    private int capacity;
    private int size;
    private int head;
    private int tail; public SimpleObjectFIFO(int cap) {
    capacity = ( cap > 0 ) ? cap : 1; // at least 1
    queue = new Object[capacity];
    head = 0;
    tail = 0;
    size = 0;
    } public synchronized int getSize() {
    return size;
    } public synchronized boolean isFull() {
    return ( size == capacity );
    } public synchronized void add(Object obj) throws InterruptedException {
    while ( isFull() ) {
    wait();
    } queue[head] = obj;
    head = ( head + 1 ) % capacity;
    size++; notifyAll(); // let any waiting threads know about change
    } public synchronized Object remove() throws InterruptedException {
    while ( size == 0 ) {
    wait();
    }

    Object obj = queue[tail];
    queue[tail] = null; // don't block GC by keeping unnecessary reference
    tail = ( tail + 1 ) % capacity;
    size--; notifyAll(); // let any waiting threads know about change return obj;
    } public synchronized void printState() {
    StringBuffer sb = new StringBuffer(); sb.append("SimpleObjectFIFO:\n");
    sb.append("       capacity=" + capacity + "\n"); sb.append("           size=" + size);
    if ( isFull() ) {
    sb.append(" - FULL");
    } else if ( size == 0 ) {
    sb.append(" - EMPTY");
    }
    sb.append("\n"); sb.append("           head=" + head + "\n");
    sb.append("           tail=" + tail + "\n"); for ( int i = 0; i < queue.length; i++ ) {
    sb.append("       queue[" + i + "]=" + queue[i] + "\n");
    } System.out.print(sb);
    }
    }
      

  10.   

    我现在也不去管为什么了, 我就用了你的代码... ... :-P
    可是 我在客户端使用一个线程不断地从服务器端读取任务的时候,如果
    当前队列里面为空,那么这个客户端程序被挂起的时候,我本来以为不
    会占用多少资源的,结果发现CPU占用率一直是100%, 这可怎么办?
    能解决吗?  这样对客户端程序的其他操作肯定影响比较大的吧:(
      

  11.   

    请问 huangry(凯撒) ,你以前问的那个关于soap的客户端和服务器端传jdom对象的问题最后怎么解决的?
      

  12.   

    to unusual(唯一):    你看以前的帖子里面, Norwaywoods() 有具体的方法在里面。 
    to Norwaywoods() :
       这个东东我也不知道该贴哪一段比较好,实在是太多了:(
       我上面没有说清楚吗?我的意思是比如 服务器端的队列的get()方法被客户端调用, 但是正好
    这个时候服务器端的队列空了,  于是这个客户端的调用过程自然就被挂
    起。  出于我写的程序的要求,客户端的类继承了Thread方法,这个线程
    的任务就是不停地从服务器端得到队列中的任务。   但是这个线程在运行而且被挂起的时候,CPU占用率实在是太吓人了,我
    很担心会影响到主程序的运行,所以我想请问是否能够避免这么多的处理器
    时间的占用?  不知道我描述清楚了没有,
      

  13.   

    to unusual(唯一):
        XMLOutputter xo = new XMLOutputter();
        String a = xo.outputString(doc);
    然后直接传送string 的值, 这是SOAP支持的基本类型。 我就是用这
    种方法的,没有对Document对象进行序列化。
     
       现在我做这个东西的时间比较紧,所以没有空研究这些,如果有空我
    会花点时间试试如何序列化的,成功了的话我再把方法贴出来。  不过本人能力... ... :(
      

  14.   

    你是不是有忙等待呀?就是类似while(i != ture).....如果有就一定要避免,这样说不清楚。还是得看代码!你把服务端的找几个有代表性的贴出来吧!
      

  15.   

    不过我觉得对于程序语言对于xml的操作就是基于dom的,jdom的序列化应该不需要咱们自己做了吧,应该至少可以转换成可以传输的dom类型吧,比如org.w3c.dom,对于常用的传输类型,应该都可以直接传输的吧?呵呵
      

  16.   

    to  unusual(唯一):
       我试过了, 500服务器错误
      

  17.   

    这就是那个服务, QRegister是一个Queue对象      
      public String sendRegister(String str){
                //return (String)QRegister.get();
                String res="";
                try{
                    res = (String)QRegister.get();
                    return  res;
                }catch(Exception e){
                    System.out.println(e.toString()+"Client Terminated");
                    try{
                    QRegister.put(res);
                    }catch(Exception e2){System.err.println(e2.toString());}
                }
                return "";
            }
      

  18.   

    我忘了说了, CPU占用率100%的是客户端这是那个客户端:
    public class RegReceiver extends Thread{  Queue RegInfo = new Queue(100);  public Document getRegInfo(){
          Document res = new Document();
          try{
              res = (Document)RegInfo.get();
          }catch(Exception e){System.err.println(e.toString());}
          return res;
      }  public boolean isEmpty(){
          if (RegInfo.getSize()==0) return true;
               else return false;
      }  public void run(){
          while(true){
          System.out.println("Attempt to Receive info");
          String endpoint ="http://"+IPAddress+":8080/axis/services/Server";
          Service  service = new Service();
          while (true){
              System.out.println("Connecting Server");          try{
                  Call     call    = (Call) service.createCall();
                  call.setTargetEndpointAddress( new java.net.URL(endpoint) );
                  call.setOperationName("sendRegister");
                  String Parameter = "";
                  String res = (String) call.invoke( new Object[] { Parameter }  );              System.out.println("received"+res);
                  SAXBuilder   ix  =  new SAXBuilder();
                  Document     doc =  ix.build(new StringReader(res));          }
              catch(Exception e){
                    System.err.println(e.toString);
              }
          }
          }
      }  public static void main(String[] args) {
        RegReceiver reg = new RegReceiver();    //reg.setServerAddress(args[0]);
        reg.start();
        while(true){
            Document doc = new Document();
            if (!reg.isEmpty()) doc = reg.getRegInfo();        XMLOutputter out  = new XMLOutputter();
            try{
              out.output(doc,System.out);
            }catch(Exception e){        }
        }
      }
    }
      

  19.   

    我确实有while(){} 语句在里面,可是照理说服务器端的程序挂起的时候这个所谓的while(){}语句照理也不再执行下去了阿! 难道不是这样的吗?
      

  20.   

    那就是你客户端有忙等待,尽量避免这种情况。to leeklaus(木子):请不要再顶了。
      

  21.   

    哦,  是我多虑了   
    把这个放在console环境中运行很占资源, 可是放到有Frame的application中去运行这个线程(比如,单击button开始运行这个线程)   就不会有这样的问题,CPU占用率就很低虽然是没事了,  可是谁知道怎么回事吗?