Azi*_*uth 0 java synchronization
我很难让我的程序正常工作.简而言之,我的程序包含几个初始线程:Main,MessageReceiver,Scheduler(使用Quartz包)和Scheduler线程调度的两种类型的线程:TraceReader和ScheduledEvent.现在,当触发TraceReader时,它会读取一个特殊的跟踪文件,并按开始时间,重复间隔(500毫秒到1秒)和结束时间来安排事件.目前,可以安排大约140个事件同时触发,这会导致大量的ConcurrentModificationException错误.现在一些代码:
public class Client { //main class
public static volatile HashMap<Integer, Request> requests;
public static class Request{
String node;
int file_id;
long sbyte;
int length;
int pc_id;
public Request(){
}
}
public static synchronized void insertRequest(int req_nr, String node, int file_id, long sbyte, int length, int pc_id) {
Request tempr = new Request();
tempr.node = node;
tempr.file_id = file_id;
tempr.sbyte = sbyte;
tempr.length = length;
tempr.pc_id = pc_id;
requests.put(req_nr, tempr);
}
public static synchronized void doSynchronized(int req_nr, String node, int file_id, long sbyte, int length, int pc_id) {
reqnr++;
String r = "P" + reqnr + "," + file_id + "," + Long.toString(sbyte) + "," + length;
insertRequest(Client.reqnr, node, file_id, sbyte, length, pc_id);
}
public class ScheduledEvent implements Job {
public synchronized boolean isRequested(long sbyte, int length, int file_id, String node) {
Request req;
Iterator<Integer> it = Client.requests.keySet().iterator();
while (it.hasNext()) {
req = Client.requests.get(it.next());
if (req.node.equals(node) && req.file_id == file_id && hits(req.sbyte, req.length, sbyte, length)) {
return true;
}
}
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
所以我基本上得到了ScheduledEvent类的isRequested方法的错误.由于有超过100个并发线程,我认为由于其他线程正在使用Client.doSynchronized()而其他线程尝试在isRequested方法中迭代请求对象而导致的错误.有没有办法让线程访问该对象同步而不使用阻塞(Thread.join()等)?
代码的基本问题是对象在不同对象(锁)上同步.要解决这个问题,不要声明同步的方法 - 在类的对象上进行同步 - 而是在请求对象本身上进行同步:
public class Client { //main class
public static void insertRequest(int req_nr, String node, int file_id, long sbyte, int length, int pc_id) {
...
synchronized (requests) {
requests.put(req_nr, tempr);
}
...
}
public class ScheduledEvent implements Job {
public boolean isRequested(long sbyte, int length, int file_id, String node) {
...
synchronized (requests) {
while (it.hasNext()) {
req = Client.requests.get(it.next());
if (req.node.equals(node) && req.file_id == file_id && hits(req.sbyte, req.length, sbyte, length)) {
return true;
}
}
}
...
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
632 次 |
| 最近记录: |