上周的时候,碰到一个问题,多线程同时处理一个 key,value 值结构的数据表,需求是这样的:要采用多线程来同时处理这些数据,但是如果与到 key 值相同的数据则要看目前有没有与之相同 key 的数据正在被处理中,如果有则等待之处理完毕后再进行,我写了一个 doSome(String key, String value)的方法,但是对这个方法加锁就不是多线程同时在处理了,主要就是这里面的 key 值应该怎么来处理为了描述我的问题,我把代码贴出吧:
Test.java
Java 代码
- public class Test extends Thread{
-
private TestDo testDo;
-
private String key;
-
private String value;
-
public Test(String key,String key2,String value){
-
this.testDo = TestDo.getInstance();
-
this.key = new String(key+key2);
-
this.value = value;
-
}
-
public static void main(String[] args) throws InterruptedException{
-
Test a = new Test("1","","1");
-
Test b = new Test("1","","2");
-
Test c = new Test("3","","3");
-
Test d = new Test("4","","4");
-
System.out.println("begin:"+(System.currentTimeMillis()/1000));
-
a.start();
-
c.start();
-
d.start();
-
b.start();
-
}
-
public void run(){
-
testDo.doSome(key, value);
-
}
- }
TestDo.java
Java 代码
- public class TestDo {
-
private static TestDo _instance = new TestDo();
-
//private static ReentrantLock lock = new ReentrantLock ();
-
public static TestDo getInstance() {
-
return _instance;
-
}
-
//public synchronized void doSome(Object key, String value) {
-
public void doSome(Object key, String value) {
-
// 以下代码是需要局部同步的代码
-
{
-
try {
-
Thread.sleep(1000);
-
System.out.println(key+":"+value + ":" + (System.currentTimeMillis() / 1000));
-
} catch (InterruptedException e) {
-
e.printStackTrace();
-
}
-
}
-
}
-
private TestDo() {
-
}
- }
前提是只能修改 TestDo 类中的 doSome 方法,期望的输出要为:
1:1:1256392306
3:3:1256392306
4:4:1256392306
1:2:1256392307
由于最后一个的 key 值与第一个相同,所以它等待第一个执行完毕后再运行,时间差 1 秒
synchronized 应用的作用域为方法或代码块,来实现同步。不知道你用的这个数据结构是不是 Map,你关注的应该是不想让同一个 key 所对应的 value 值被同时操作,所以我们只要关注这一点就行了,就是在对 value 写操作时进行同步,比如 HashMap 里面,你只要在 put 方法的修饰符后面加上 synchronized 就可以达到同步了,这样还会提高效率,因为我们关注的就是这一点啊,我假设你用的是 HashMap,我们重写他的方法,只要加 synchronized,如:
public synchronized V put(K key, V value) {
if (key == null)
return putForNullKey(value);
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
for (Entry e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(hash, key, value, i);
return null;
}
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于