本帖最后由 Kanepan 于 2010-07-09 10:50:44 编辑

解决方案 »

  1.   

    你传入的每个Integer都是new出来的吧?这些锁都由你自己管理就好了,不要new出来
      

  2.   


           class ThreadTest extends Thread {
        final private int ID;
        final private Map<Integer,Object> map = new Hashtable<Integer, Object>();     private ThreadTest(int id) { // 为什么要私有??????
            super();
            ID = id;
        }     public void run() {
         if(map.get(ID) == null){
         map.put(ID, new Object());
         }
        
            synchronized (map.get(ID)) {
                // do sth here;
            }
        }
    }照你的给该了下,没时间给你测试了,但思路是这样的。
      

  3.   

    你的ID是final的,除了第一次赋值,怎么会变化呢?没明白 
      

  4.   

    不知道可以不/*
     * file: SyncID.java
     * class: SyncID
     *
     * description: 
     *
     * @author:  leisore
     * @version: V1.0.0
     */
    package cn.leisore.daily._2010_07_09;import java.io.Serializable;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Random;public class SyncID {    public static void main(String[] args) {
            
            for (int i = 0; i < 10; i++) {
                new ThreadTest(TID.getID()).start();
                new ThreadTest(TID.getID(i)).start();
            }
        }
        
       static class ThreadTest extends Thread {
            final private TID id;
            static Random rand = new Random();        private ThreadTest(TID id) {
                this.id = id;
            }        public void run() {
                synchronized (id) {
                    System.out.println(id.id());
                    try {
                        Thread.sleep(Math.abs(rand.nextInt(2000)));
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    final class TID implements Serializable {
        
        private static final long serialVersionUID = 1L;
        
        static int ID_COUNTER = 0;
        static Map<Integer, TID> cache = new HashMap<Integer, TID>();    private final int id;
        private TID(int id) {
            this.id = id;
        }
        
        public synchronized static TID getID (int readId) {
            if (cache.get(readId) == null) {
                cache.put(readId, new TID(readId));
            }
            return cache.get(readId);
        }
        
        public synchronized static TID getID () {
            int counter = ID_COUNTER;
            int nextId = counter++;
            if (cache.get(nextId) == null) {
                cache.put(nextId, new TID(nextId));
                ID_COUNTER++;
            }
            return cache.get(nextId);
        }
        
        public int id() {
            return this.id;
        }
    }
      

  5.   

    支持2楼的想法:
    class ThreadTest extends Thread {
            final private int ID;
            private static Map<Integer,Object> map = new Hashtable<Integer, Object>();        ThreadTest(int id) {
                 super();
                ID = id;
                if(map.get(ID) == null){
                    map.put(ID, new Object());
                }
            }        public void run() {
                synchronized (map.get(ID)) {
                    // do sth here;
                }
            }
        }
      

  6.   

    类似的就是让那些数值上相同的id,程序上是同一个对象,默认缓存范围太小-128~127
    自己按照Integer源码的思路,对传入的Integer对象重新与自己实现的缓存化Integer对象挂钩,保证相同数值的Integer指向的是同一个对象
      

  7.   

    谢谢各位5楼的代码写在构造器中 能保证同步吗?
    如果写在RUN里还得锁一下map        public void run() {
                synchronized(map){
                  if(map.get(ID) == null){
                    map.put(ID, new Object());
                  }
                }
                
                synchronized (map.get(ID)) {
                    // do sth here;
                }
            }
      

  8.   

    你很难做到这么细粒度的同步的。可以采用分离锁(lock striping)模式进行同步处理:Object[] locks = new Object[16];initialize locks...synchronized(locks[id & 0xff]) {
        ....
    }
      

  9.   


    更正一下:synchronized(locks[id & 0xf]) {
        ....
    }
      

  10.   

    5楼的代码不错,可以用。
    2楼的代码貌似有问题,map应该放到Thread外面,如果放在里面,岂不每个线程生成一个map?