例:
A转账给B,
C转账给B.
........
入库操作. 1.需要效率,不能把没有冲突的人给锁住,比如:e转账给f,这个时候,ab,ef同时进行,对于A->b做完后才能C->B.
2.暂时想法是把正在进行的人员放入到一个静态的map中(成对放入,比如A,B),
每次先检查要处理的人是否有其中一个正在处理,如果正在处理,那么循环等.如果正在处理的人,处理完了,那么就从map中移除出去,后来的C->B就放入....依次循环.. 但如果真的并发了那么放入map的时候可能出现并发,但我不能去锁方法,锁方法就违背了第一个.
其实也不止放的时候,判断map是否存在该人,放入时,删除时,都存在并发的问题. 谁有并发的处理经验?求教. 以这个例子再次说明下:
A->B
C->B
E->F
期望,如果三对同时做的话,那么a,b和e,f先处理,c,b等待. 但愿大家明白我意思.
A转账给B,
C转账给B.
........
入库操作. 1.需要效率,不能把没有冲突的人给锁住,比如:e转账给f,这个时候,ab,ef同时进行,对于A->b做完后才能C->B.
2.暂时想法是把正在进行的人员放入到一个静态的map中(成对放入,比如A,B),
每次先检查要处理的人是否有其中一个正在处理,如果正在处理,那么循环等.如果正在处理的人,处理完了,那么就从map中移除出去,后来的C->B就放入....依次循环.. 但如果真的并发了那么放入map的时候可能出现并发,但我不能去锁方法,锁方法就违背了第一个.
其实也不止放的时候,判断map是否存在该人,放入时,删除时,都存在并发的问题. 谁有并发的处理经验?求教. 以这个例子再次说明下:
A->B
C->B
E->F
期望,如果三对同时做的话,那么a,b和e,f先处理,c,b等待. 但愿大家明白我意思.
Lock类和Condition类jdk 1.5新线程同步类。
public interface Transfer {
void action(Transfer transfer);
}public class TransferImp implements Transfer {
public synchronized action(Transfer transfer) {
synchronized (transfer) {
...
}
}
}public class TransferThread implements Runnable {
private Transfer from;
private Transfer to;
public TransferThread(Transfer from, Transfer to) {
this.from = from;
this.to = to;
}
public void run() {
from.action(to);
}
}public class Test {
public void static main(String[] args) {
// 如果是Web环境下你只要将地下申明的a,b,c,e,f对象放入全局就行(如static,application,session等),根据你实际情况
Transfer a = new TransferImp();
Transfer b = new TransferImp();
Transfer c = new TransferImp();
Transfer e = new TransferImp();
Transfer f = new TransferImp();
Thread t1 = new Thread(new TransferThread(a,b));
Thread t2 = new Thread(new TransferThread(c,b));
Thread t3 = new Thread(new TransferThread(e,f));
t1.start();
t2.start();
t3.start();
}
}
人员为N,你这个就不是很可取了,有人来注册了,就是多一个人了,像你这么做,别人不操作的你也new出来了,压力太大.
只要保证对同一个人的操作都是在同一个对象上,不同人的操作在不同的对象上,就可以实现同步一个人,而不影响其他人了。
可以把Person对象都放在一个全局的PersonMap中,需要操作的时候从PersonMap中获取,保证只有一个人只有实例。如果楼主觉得效率低,也可以搞个优化,定时清理PersonMap中那些不用的Person。下面代码模拟了一下,至于Map的问题可以另外优化。
public class Translate extends Thread{
private Person p1;
private Person p2;
private int money;
public Translate(Person p1, Person p2, int money) {
this.p1 = p1;
this.p2 = p2;
this.money = money;
}
@Override
public void run() {
try {
p1.del(money);
p2.add(money);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Person pA = new Person("A", 200);
Person pB = new Person("B", 200);
Person pC = new Person("C", 200);
Person pD = new Person("D", 200);
Translate t1 = new Translate(pA, pB, 20);
Translate t2 = new Translate(pC, pB, 20);
Translate t3 = new Translate(pC, pD, 20);
t1.start();
t2.start();
t3.start();
}
}class Person {
private double account;
private String name;
public Person(String name, double account) {
this.account = account;
this.name = name;
}
public synchronized void add(double money) throws InterruptedException {
account += money;
printMenoy("add");
Thread.sleep(2000); // 处理时间,通过这来看出其他线程的阻塞
}
public synchronized void del(double money) throws InterruptedException {
account -= money;
printMenoy("delete");
}
public void printMenoy(String deal) {
System.out.println("Deal with: " + deal + " -- " + name + "'s money :" + account);
}
}
就是PersonMap中,保证每个人只有一个实例
呵呵,仔细看题目,AB做的时候,CB就要等待,因为AB没有做完.一对人为一次完整的交易,
你的做法两个B同时做了.若,放到map中,先不说人有多么的多的问题.
map移除和获取并发的时候就已经出问题了.(别告诉我说用hashTable,更别告诉我用Collections.synchronizedMap(new LinkedHashMap<K, V>()))
我的处理,B操作的时候是被锁住的,所以CB要等AB完成才做的,你没看清楚。(可能你的意思是C动了…)
另外你说Map的问题,是存在,不过现在1.5可以用ConcurrentHashMap,这个还是快了不少。
本来你要减少冲突,就不得不牺牲其他性能。何况这里只是做一下人的缓存,比你说的多人冲突,等待效率更定要好。
我在13楼中已经说明如果你用
hashMap或
Collections.synchronizedMap(new LinkedHashMap())或
ConcurrentHashMap都会产生异常的问题,
要保证效率,不能将锁的范围扩大.你说B是锁住了,对,是锁住了,所有人都进不来了,该进来的也进不来了!
想:
当ab来的时候,处理到a的时候,a完,正在处理B,这个时候又来,ac,你的a又处理了,但ab这对没有处理完啊?
并发并发并发并发并发并发并发并发并发并发并发并发并发并发并发并发并发并发并发并发并发
你的这个案例不需要用到wait和notify的(他们最适合的场合是生产者消费者模式),当然用它也会有解决方案。
我不强制你要接受我的方案,不过我还是认为我那方案相对还是不错的,从你回复的内容来看你还没完全理解我给你提出的方案,你说的问题,根本就不是问题。
讨论到此为止吧。