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; } } }照你的给该了下,没时间给你测试了,但思路是这样的。
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; } }
支持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; } } }
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;
}
}
}照你的给该了下,没时间给你测试了,但思路是这样的。
* 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;
}
}
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;
}
}
}
自己按照Integer源码的思路,对传入的Integer对象重新与自己实现的缓存化Integer对象挂钩,保证相同数值的Integer指向的是同一个对象
如果写在RUN里还得锁一下map public void run() {
synchronized(map){
if(map.get(ID) == null){
map.put(ID, new Object());
}
}
synchronized (map.get(ID)) {
// do sth here;
}
}
....
}
更正一下:synchronized(locks[id & 0xf]) {
....
}
2楼的代码貌似有问题,map应该放到Thread外面,如果放在里面,岂不每个线程生成一个map?