以代码来说明问题吧。
我的本义是让RunThread中的《模拟事件处理》部分程序能够按照创建时候传入的参数“1”“2”“3”等独立执行下去,即:每个“1”是顺序的,每个“2”是顺序的。
以下代码抽取自俺做的一个项目,因为项目其他代码基本成型,不宜大的修改。
所以主要类:LockClass如何实现就成了问题所在,请大家帮忙。public class Untitled1 {
  public static void main(String[] args) {
    Untitled1 untitled1 = new Untitled1();
    untitled1.go();
  }  public void go() {
    new RunThread("1").start();
    new RunThread("2").start();
    new RunThread("1").start();
    new RunThread("2").start();
    new RunThread("1").start();
    new RunThread("3").start();
  }
}class RunThread
    extends Thread {
  LockClass lockClass;
  String str;  RunThread(String str) {
    this.str = str;
    lockClass = new LockClass(str);
  }  public void run() {
    System.out.println("申请锁定 " + hashCode() + " " + str);
    lockClass.lock();
    try {
      System.out.println("锁定 " + hashCode() + " " + str);
      try {
        //模拟事件处理
        Thread.sleep(10000);
      }
      catch (InterruptedException ex) {
      }
    }
    finally {
      System.out.println("申请释放 " + hashCode() + " " + str);
      lockClass.unlock();
      System.out.println("释放 " + hashCode() + " " + str);
    }
  }
}class LockClass {
//使用静态的Object供同步?...
  String str;
  LockClass(String str) {
    this.str = str;
  }  public void lock() {
    //如何实现?
  }  public void unlock() {
    //如何实现?
  }
}

解决方案 »

  1.   

    class LockClass
    {    LockClass(String str)
        {
            this.str = str;
        }    public synchronized void lock()
        {
            while (busy)
            {
                try
                {
                    wait();
                }
                catch (java.lang.InterruptedException ex)
                {
    // Eat it.
                }
            }
            busy = true;
        }    public synchronized void unlock()
        {
            if (!busy)
            {
                throw new Error("freeing non-busy lock");
            }
            busy = false;
            notifyAll();
        }    boolean busy = false;
        String str;
    }
      

  2.   

    这种方式不对,你的LockClass 应该在某个循环中才对。
      

  3.   

    to homesos(熊猫贩子),谢谢,不过您的办法确实行不通
    kindani(kindani),您是说我的办法不对还是homesos(熊猫贩子)的办法不对,请明示
      

  4.   

    kingfish(八百里秦川@龙城异客),请明示。
    同时,我希望尽量在LockClass中修改,因为其他部分代码相对比较庞大。同时:
    我的本义是让RunThread中的《模拟事件处理》部分程序能够按照创建时候传入的参数“1”“2”“3”等独立执行下去,即:每个“1”是顺序的,每个“2”是顺序的。
      

  5.   

    如果是可以修改RunThread, 那么问题其实就是根据str产生一个同步的对象,
    大致如下
      public void run() {
        System.out.println("申请锁定 " + hashCode() + " " + str);
        synchronized (LockClass.getLock(str)) {
          System.out.println("锁定 " + hashCode() + " " + str);
          try {
            Thread.sleep(10000);
          }
          catch (InterruptedException ex) {
          }
        }
      }
      

  6.   

    嗯,谢谢,我再想想。您的LockClass.getLock()中如何实现呢?是使用静态元素还是其他方法呢?
      

  7.   

    不修改RunThread也行,大致如下class RunThread
        extends Thread {
      LockClass lockClass;
      String str;
      RunThread(String str) {
        lockClass = LockClass.getLock(str);    //这个改动过
        this.str = str;
      }   public void run() {
        System.out.println("申请锁定 " + hashCode() + " " + str);
        lockClass.lock();
        System.out.println("锁定 " + hashCode() + " " + str);
        try {
          Thread.sleep(10000);
        }
        catch (InterruptedException ex) {
        }
        finally {
          System.out.println("释放 " + hashCode() + " " + str);
          lockClass.unlock();
        }
      }
    }class LockClass {
      private static HashMap hm = new HashMap();
      private String str;
      private LockClass(String str) {
        this.str = str;
      }  public synchronized static LockClass getLock(String str) {
        LockClass lc = (LockClass) hm.get(str);
        if (lc == null) {
          lc = new LockClass(str);
          hm.put(str, lc);
        }    return lc;
      }  private boolean isUsed = false;
      public synchronized void lock() {
        if (isUsed) {
          try {
            wait();
          }
          catch (InterruptedException ex) {
            System.out.println(ex);
          }
        }
        isUsed = true;
      }  public synchronized void unlock() {
        isUsed = false;
        notifyAll();
      }
    }
      

  8.   

    public class Untitled1 {
      public static void main(String[] args) {
        Untitled1 untitled1 = new Untitled1();
        untitled1.go();
      }  public void go() {
        new RunThread("1").start();
        new RunThread("2").start();
        new RunThread("1").start();
        new RunThread("2").start();
        new RunThread("1").start();
        new RunThread("3").start();
      }
    }class RunThread extends Thread {  String str;  RunThread(String str) {
        this.str = str;
        lockClass = LockClass.add(str);
      }  public void run() {
        System.out.println("申请锁定 " + hashCode() + " " + str);
        synchronized(LockClass.getLock(str)) {
            try {
              System.out.println("锁定 " + hashCode() + " " + str);
              try {
                //模拟事件处理
                Thread.sleep(10000);
              }
              catch (InterruptedException ex) {
              }
            }
            finally {
              System.out.println("申请释放 " + hashCode() + " " + str);
              lockClass.unlock();
              System.out.println("释放 " + hashCode() + " " + str);
            }
          }
        }
        
    }class LockClass {  ArrayList list = new ArrayList();
      
      public static void add(String str) {
        synchronized(list) {
         if(!list.contains(str)) 
           list.add(str);      
        }
      }
      
      public static String getLock(String str) throw Exception{
        synchronized(list) {
          int index = 0;
          index = list.indexOf(str);
          if(index == -1) throw new Exception;
          return (String)(list.get(i);
        }
      }  
      
    }
      

  9.   

    ArrayList list = new ArrayList();应该改为
    private static ArrayList list = new ArrayList();
      

  10.   

    刚刚编译了一下,好象是可以的。import java.util.*;public class Untitled1 {
      public static void main(String[] args) {
        Untitled1 untitled1 = new Untitled1();
        untitled1.go();
      }  public void go() {
        new RunThread("1").start();
        new RunThread("2").start();
        new RunThread("1").start();
        new RunThread("2").start();
        new RunThread("1").start();
        new RunThread("3").start();
      }
    }class RunThread extends Thread {  String str;  RunThread(String str) {
        this.str = str;
        LockClass.add(str);
      }  public void run() {
        System.out.println("申请锁定 " + hashCode() + " " + str);
        try {
         synchronized(LockClass.getLock(str)) {
            try {
              System.out.println("锁定 " + hashCode() + " " + str);
              try {
                System.out.println(str);
                Thread.sleep(10000);
              }
              catch (InterruptedException ex) {
              }
            }
            finally {
              System.out.println("申请释放 " + hashCode() + " " + str);          System.out.println("释放 " + hashCode() + " " + str);
            }
          }
         }
         catch(Exception ex) {
          System.out.println(ex);
        }
    }    
        
    }class LockClass { private static ArrayList list = new ArrayList();
      
      public static void add(String str) {
        synchronized(list) {
         if(!list.contains(str)) 
           list.add(str);      
        }
      }
      
      public static String getLock(String str) throws Exception{
        synchronized(list) {
          int index = 0;
          index = list.indexOf(str);
          if(index == -1) throw new Exception();
          return (String)(list.get(index));
        }
      }  
      
    }
      

  11.   

    kingfish(八百里秦川@龙城异客) ,刚才测试了一下您写的这段程序,发现结果还不对。
    但仔细看了一遍代码,还没有找到原因。正在继续看您写的这段代码。有消息,马上回来汇报。
    再次表示感谢!申请锁定 27338224 1
    锁定 27338224 1
    申请锁定 12700959 2
    锁定 12700959 2
    申请锁定 25276323 1
    申请锁定 20051738 2
    申请锁定 22413802 1
    申请锁定 26726999 3
    锁定 26726999 3
    释放 27338224 1
    锁定 25276323 1
    释放 12700959 2
    锁定 20051738 2
    释放 26726999 3
    释放 25276323 1
    释放 20051738 2
    锁定 22413802 1
    释放 22413802 1
      

  12.   

    对了notifyAll();需要改成notify()的,否则也许会出问题。
      

  13.   

    new RunThread("1").start(); //A
     new RunThread("1").start(); //B
     new RunThread("1").start(); //C刚又看了看,觉得上面的代码可能还是不满足你的要求。//每个“1”是顺序的
    A在执行时,B和C在wait, notify后那么到底B和C谁获得执行权,是由JVM决定的。
    如果你的意思是B必须比C先执行,那么上面代码不满足
      

  14.   

    参考下这个~
    -------------------------
    // Lock.java//// This class implements a boolean lock object in java// class Lock extends Object {       private boolean m_bLocked = false;        public synchronized void lock() {              // if some other thread locked this object then we need to wait              // until they release the lock              if( m_bLocked ) {                     Do {                            Try {                                   // this releases the synchronized that we are in                                   // then waits for a notify to be called in this object                                   // then does a synchronized again before continuing                                   wait();                            } catch( InterruptedException e ) {                                   e.printStackTrace();                            } catch( Exception e ) {                                   e.printStackTrace();                            }                     } while( m_bLocked );      // we can't leave until we got the lock, which                                                               // we may not have got if an exception occured              }               m_bLocked = true;       }        public synchronized boolean lock( long milliSeconds ) {              if( m_bLocked ) {                     try                     {                            wait( milliSeconds );                     } catch( InterruptedException e ) {                            e.printStackTrace();                     }                      if( m_bLocked ) {                            return false;                     }              }               m_bLocked = true;              return true;       }        public synchronized boolean lock( long milliSeconds, int nanoSeconds )       {              if( m_bLocked ) {                     try                     {                            wait( milliSeconds, nanoSeconds );                     } catch( InterruptedException e ) {                            e.printStackTrace();                     }                      if( m_bLocked ) {                            return false;                     }              }               m_bLocked = true;              return true;       }        public synchronized void releaseLock() {              if( m_bLocked ) {                     m_bLocked = false;                     notify();              }       }        public synchronized boolean isLocked() {              return m_bLocked;       }}
      

  15.   

    有问题!
    RunThread.str相同的RunThread实例,应该持有相同的 LockClass,
    而不是每个RunThread 都有一个不同的LockClass
      

  16.   

    to cozmic(蓝色的猪),
    kingfish(八百里秦川@龙城异客) 的getLock就是实现这个功能的。
      

  17.   

    乱了乱了,一切都乱了,此程序直接使用 java y.Y 运行,一切符合要求。可压缩成jar包后,即使用jar cvfm y.jar MANIFEST.MF y后使用java -jar y.jar执行却一切都乱套了。晕啊。package y;import java.util.*;public class Y {
      public static void main(String[] args) {
        Y untitled1 = new Y();
        untitled1.go();
      }  public void go() {
        for (int i = 0; i < 100; i++) {
          new RunThread("1").start();
          new RunThread("1").start();
          new RunThread("1").start();
          new RunThread("1").start();
          new RunThread("1").start();
        }
      }
    }class RunThread
        extends Thread {
      LockClass lockClass;
      String str;
      RunThread(String str) {
        lockClass = LockClass.getLock(str); //这个改动过
        this.str = str;
      }  public void run() {
        System.out.println("申请锁 " + hashCode() + " " + str);
        lockClass.lock();
        System.out.println("执行中" + hashCode() + " " + str);
        try {
          Thread.sleep(100);
        }
        catch (InterruptedException ex) {
        }
        finally {
          lockClass.unlock();
        }
      }
    }class LockClass {
      private static HashMap hm = new HashMap();
      private String str;
      private LockClass(String str) {
        this.str = str;
      }  public synchronized static LockClass getLock(String str) {
        LockClass lc = (LockClass) hm.get(str);
        if (lc == null) {
          lc = new LockClass(str);
          hm.put(str, lc);
        }    return lc;
      }  private boolean isUsed = false;  public synchronized void lock() {
        if (isUsed) {
          try {
            wait();
          }
          catch (InterruptedException ex) {
            System.out.println(ex);
          }
        }
        isUsed = true;
      }  public synchronized void unlock() {
        isUsed = false;
        notify();
        System.out.println("释放完了 " + hashCode() + " " + str);
      }
    }
      

  18.   

    回复人:riverwater(小河流水) ( 四级(中级)) 信誉:100  2005-08-01 10:05:00  得分:0
    to cozmic(蓝色的猪),
    kingfish(八百里秦川@龙城异客) 的getLock就是实现这个功能的。
    ------------------------------------------------
    呵呵,得用个 多态模式 样的东东~~
    ------------------------------------------------
      

  19.   

    我觉得在kingfish 的代码中,要做一些修改,public synchronized void lock() {
        while(isUsed) {    //在这一行修改,原为: if (isUsed) {
          try {
            wait();
          }
          catch (InterruptedException ex) {
            System.out.println(ex);
          }
        }
        isUsed = true;
      }
      

  20.   

    我觉得这样更好:
     public synchronized void lock() {
    if( isUsed ) {
    Do {
    Try {
    wait();
    } catch( InterruptedException e ) {
    e.printStackTrace();
    } catch( Exception e ) {
    e.printStackTrace();
    } while( isUsed ); 
    }
      

  21.   

    把RunThread 中的 hasnCode() 变为 this.getName() 看一看
    打了包 也没有乱呀,
      

  22.   

    贴出我实现的:
    package com.cozmic.Thread;
    import java.util.*;public class MultiThreadInSameGroupExclusiveRunning {
    public static void main(String[] args) {
    MultiThreadInSameGroupExclusiveRunning untitled1
    = new MultiThreadInSameGroupExclusiveRunning();
    untitled1.go();
    }public void go() {
    for (int i = 0; i < 10; i++) {
    new RunThread(“1“).start();
    new RunThread(“1“).start();
    new RunThread(“2“).start();
    }}
    }class RunThread
    extends Thread {
    LockClass lockClass;
    String str;
    RunThread(String str) {
    lockClass = LockClass.getLock(str); //这个改动过
    this.str = str;
    }public void run() {
    System.out.println(“申请锁 ” this.getName() “ “ + str);
    lockClass.lock();
    System.out.println(“执行中” this.getName() “ “ + str);
    try {
    Thread.sleep(10);
    }catch (InterruptedException ex) {
    }finally {
    lockClass.unlock();
    }}
    }class LockClass {
    private static HashMap hm = new HashMap();
    private String str;
    private LockClass(String str) {
    this.str = str;
    }//多例模式
    public synchronized static LockClass getLock(String str) {
    LockClass lc = (LockClass) hm.get(str);
    if (lc == null) {
    lc = new LockClass(str);
    hm.put(str, lc);
    }return lc;
    }private boolean isUsed = false;public synchronized void lock() {
    if (isUsed) {
    try {
    wait();
    }catch (InterruptedException ex) {
    System.out.println(ex);
    }}
    isUsed = true;
    }public synchronized void unlock() {
    isUsed = false;
    notify();
    System.out.println(“释放完了 ” hashCode() “ ” + str);
    }}