【求助】java多线程资源同步问题 本帖最后由 crazyafei 于 2013-05-15 10:15:38 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 用一个线程同步类封装设备接口,比如说你这个Demo类,所有方法加上同步锁,然后让其他组件都通过这个封装类去访问设备 得根据不同的粒度来加锁public boolean operate1()和public boolean operate2()是否互斥?还是说:只要一个线程处于connect状态,别的线程都不能做任何操作?只有等disconnect以后,别的线程才可以操作? 里面所有的方法都是互斥的,只要有任何操作connect了设备,其它任何对设备的操作都会导致异常。也就是说只要有线程在使用operate1(),别的任何线程使用connect都会导致异常。 现在是这样在写,加了个单例模式,然后每个方法都有同步代码块,运行到是没报错了,但是从log4j输出的日志上看是错的,正在奇怪中……public class Demo { private String ip; private int port; private static Demo instance = new Demo(); private Demo(){ } public Demo getInstance(){ return this.instance; } // 连接设备 public boolean connect(String ip, int port) { synchronized (this) { this.ip = ip; this.port = port; // 这里是连接设备的代码,根据返回值判定连接状态 return true; } } // 操作设备 public boolean operate1() { synchronized (this) { // 根据IP地址操作设备,返回操作结果 return false; } } // 操作设备 public boolean operate2() { synchronized (this) { // 根据IP地址操作设备,返回操作结果 return false; } } // 断开设备 public boolean disconnect() { synchronized (this) { // 断开设备连接 return true; } }} 现在是这样在写,加了个单例模式,然后每个方法都有同步代码块,运行到是没报错了,但是从log4j输出的日志上看是错的,正在奇怪中……public class Demo { private String ip; private int port; private static Demo instance = new Demo(); private Demo(){ } public Demo getInstance(){ return this.instance; } // 连接设备 public boolean connect(String ip, int port) { synchronized (this) { this.ip = ip; this.port = port; // 这里是连接设备的代码,根据返回值判定连接状态 return true; } } // 操作设备 public boolean operate1() { synchronized (this) { // 根据IP地址操作设备,返回操作结果 return false; } } // 操作设备 public boolean operate2() { synchronized (this) { // 根据IP地址操作设备,返回操作结果 return false; } } // 断开设备 public boolean disconnect() { synchronized (this) { // 断开设备连接 return true; } }}你这种做法虽然是单例,而且每个方法都加了锁。但是你却没有办法杜绝这种访问。比如访问顺序是connectconnectoperate1operate2disconnectoperate1operate2disconnect因为你是每个方法单独加锁的,你是没有办法保证方法的调用顺序的。 LZ,我对你的问题有点疑问,是要一个线程按顺序调用完Demo类所有的方法后,才让别的线程进来呢?还是说一个线程在调用Demo类的某个方法时,别的线程禁止调用Demo类的其他方法?如果是第二种试试这样行不行,利用静态类特性加互斥锁。在 Demo 类中写一个静态内部类,这个内部类才是真正实现连接设备,Demo 只是调用该内部类的方法。public class Demo{ private String ip; private int port; private Demo(){} private static class DemoHolder{ private static Demo instance = new OnlyModel(); } public static Demo getInstance(){ return OnlyModelHolder.instance; } pirvate static class Connect{ // Connect的连接设备 public static boolean connect(String ip, int port) { ... } // Connect的操作设备 public static boolean operate1() { ... } } public static boolean connect(String ip, int port) { synchronized(Connect.class){ Connect.connect(); } } public static boolean operate1() { synchronized(Connect.class){ Connect.operate1(); } }} 应该是你说的第一种情况,一个线程用connect方法连接设备,然后做一些操作采集数据,最后用disconnect断开设备连接,在这过程中,不允许其它线程使用这个类里面的任意方法。 将所有业务方法按顺序放到一个公共的同步方法中。Dome类的方法 //如果这些方法让其他类用,那就将其私有化 private boolean connect(String ip, int port) { ... } private boolean operate1() { ... } public synchronized boolean operate(String ip, int port){ if(!connect(String ip, int port)) retuen false; if(!operate1()){ retuen false; } //... return true; } 难题求解决方法:将下载的web页面的内容转化为纯文本 对话框问题 有一起报传智博客java基础班的吗?团报优惠,本人也报名 股票真的让人疯了! 一个applet的程序 计算阶乘相加得 帮我看看那错了?怎么改? 谁知到北京朝阳区安翔路的具体位置??告诉我好吗,我要找中国音乐学院 Java每天开发代码量多少行比较合适 急!JAVA中写文件的问题! 问个关于JTable中CellEditor为ComboBox的问题 麻烦大家一下(JAVA) Java读取控制 error code=109 message=管道已结束 进程 同步问题
得根据不同的粒度来加锁public boolean operate1()和public boolean operate2()是否互斥?还是说:只要一个线程处于connect状态,别的线程都不能做任何操作?只有等disconnect以后,别的线程才可以操作?
也就是说只要有线程在使用operate1(),别的任何线程使用connect都会导致异常。
private String ip;
private int port;
private static Demo instance = new Demo();
private Demo(){
}
public Demo getInstance(){
return this.instance;
} // 连接设备
public boolean connect(String ip, int port) {
synchronized (this) {
this.ip = ip;
this.port = port;
// 这里是连接设备的代码,根据返回值判定连接状态
return true;
}
} // 操作设备
public boolean operate1() {
synchronized (this) {
// 根据IP地址操作设备,返回操作结果
return false;
}
} // 操作设备
public boolean operate2() {
synchronized (this) {
// 根据IP地址操作设备,返回操作结果
return false;
}
} // 断开设备
public boolean disconnect() {
synchronized (this) {
// 断开设备连接
return true;
}
}
}
private String ip;
private int port;
private static Demo instance = new Demo();
private Demo(){
}
public Demo getInstance(){
return this.instance;
} // 连接设备
public boolean connect(String ip, int port) {
synchronized (this) {
this.ip = ip;
this.port = port;
// 这里是连接设备的代码,根据返回值判定连接状态
return true;
}
} // 操作设备
public boolean operate1() {
synchronized (this) {
// 根据IP地址操作设备,返回操作结果
return false;
}
} // 操作设备
public boolean operate2() {
synchronized (this) {
// 根据IP地址操作设备,返回操作结果
return false;
}
} // 断开设备
public boolean disconnect() {
synchronized (this) {
// 断开设备连接
return true;
}
}
}
你这种做法虽然是单例,而且每个方法都加了锁。
但是你却没有办法杜绝这种访问。
比如访问顺序是
connect
connect
operate1
operate2
disconnect
operate1
operate2
disconnect因为你是每个方法单独加锁的,你是没有办法保证方法的调用顺序的。
试试这样行不行,利用静态类特性加互斥锁。
在 Demo 类中写一个静态内部类,这个内部类才是真正实现连接设备,Demo 只是调用该内部类的方法。public class Demo{
private String ip;
private int port; private Demo(){}
private static class DemoHolder{
private static Demo instance = new OnlyModel();
} public static Demo getInstance(){
return OnlyModelHolder.instance;
} pirvate static class Connect{
// Connect的连接设备
public static boolean connect(String ip, int port) {
...
} // Connect的操作设备
public static boolean operate1() {
...
}
} public static boolean connect(String ip, int port) {
synchronized(Connect.class){
Connect.connect();
}
} public static boolean operate1() {
synchronized(Connect.class){
Connect.operate1();
}
}
}
应该是你说的第一种情况,一个线程用connect方法连接设备,然后做一些操作采集数据,最后用disconnect断开设备连接,在这过程中,不允许其它线程使用这个类里面的任意方法。
//如果这些方法让其他类用,那就将其私有化
private boolean connect(String ip, int port) {
...
}
private boolean operate1() {
...
} public synchronized boolean operate(String ip, int port){
if(!connect(String ip, int port))
retuen false; if(!operate1()){
retuen false;
}
//...
return true;
}