比如说:
String tt[] = new String[100];
synchrnized(tt)
{
.....
}
即当多线程访问tt数组时要同步。但是有一个问题,现在这种情况是线程1和线程2同时访问tt,即使两个线程不是访问同一个地址,比如:线程1访问tt[0],线程2访问tt[1],线程间也要加锁,这大大影响效率。有没有什么办法让多线访问一个地址时才加锁?即线程1访问tt[0],线程2访问tt[1],线程间不加锁;只有线程1访问tt[0],线程2也访问tt[0],线程间才加锁?
我试过
synchrnized(tt[i])
{
.....
}
但是不行,系统还是默认块是tt,而不是tt的某个指针对象。苦恼了很久,现在手底下的项目等着用这种技术,望高手指点,不胜感激。
String tt[] = new String[100];
synchrnized(tt)
{
.....
}
即当多线程访问tt数组时要同步。但是有一个问题,现在这种情况是线程1和线程2同时访问tt,即使两个线程不是访问同一个地址,比如:线程1访问tt[0],线程2访问tt[1],线程间也要加锁,这大大影响效率。有没有什么办法让多线访问一个地址时才加锁?即线程1访问tt[0],线程2访问tt[1],线程间不加锁;只有线程1访问tt[0],线程2也访问tt[0],线程间才加锁?
我试过
synchrnized(tt[i])
{
.....
}
但是不行,系统还是默认块是tt,而不是tt的某个指针对象。苦恼了很久,现在手底下的项目等着用这种技术,望高手指点,不胜感激。
void foo() {
String[] tt new String[]....;
syncrhonized(tt) { // 或者tt[i]
}
}即使是全局的,tt[i] 也可以随时变更,比如线程1锁定的时候tt[0]="abc",到线程2就变成了"xyz",自然锁不住。而且,即使都是"abc",它们也并不一定是同一个对象。所以锁定字符串的时候一般使用"...".intern()。回到你的问题,你的目的是同步tt数组。你可以
private final Object lock = new Object();public void foo() {
synchronized(lock) {
// tt operation
}
}// 这个也可以
public synchronized void foo2() {
// tt operation
}
private final Object lock = new Object();public void foo() {
synchronized(lock) {
// tt operation
}
}学习
private Object[] locks; private final static int DEFAULT_LOCK_COUNT = 16; public GuardString(int len) {
this.str = new String[len];
this.locks = new Object[DEFAULT_LOCK_COUNT];
} public void setValue(int index, String s) {
checkIndex(index);
synchronized (lockObject(index)) {
str[index] = s;
}
} public String removeValue(int index) {
checkIndex(index);
synchronized (lockObject(index)) {
return str[index];
}
} private void checkIndex(int index) {
if(index < 0) {
throw new IllegalArgumentException("index must be greater than or equals 0");
}
if(index > str.length - 1) {
throw new IllegalArgumentException("index must be less than " + (str.length - 1));
}
} private Object lockObject(int index) {
return locks[index % DEFAULT_LOCK_COUNT];
}
}
呵呵,我初始化了哦 :-) public GuardString(int len) {
this.str = new String[len];
this.locks = new Object[DEFAULT_LOCK_COUNT];
}
this.str = new String[len];
initLocks();
} private void initLocks() {
locks = new Object[DEFAULT_LOCK_COUNT];
for(int i = 0; i < locks.length; i++) {
locks[i] = new Object();
}
}