菜鸟求教synchronized 同步锁问题

冰释绿茵 2011-09-14 06:00:05
服务器—客户机通讯问题

类Create 里有个方法,是个死循环,负责创建新的通讯线程
客户机A连接成功,创建一个新线程,专门用于和A通讯
客户机B连接成功,创建一个新线程,专门用于和B通讯

问题来了,
服务器这边某个类有个变量x,
接收到客户机A数据a则在线程里进行x+=a操作;
接收到客户机B数据b则在线程里进行x-=b操作;
服务器同时接收到A和B的数据a和b;

由于同时到达,而线程是独立的,所以同时对x进行操作,这显然出问题。
显然要用到同步锁,我是新手不会用,不知道要锁的对象是谁,
x是一个基本类型,显然不能锁x。求解啊,一下午看资料也搞不懂这个同步锁。
智力有限,求高手帮忙解决啊,越详细越好。
...全文
105 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
magong 2011-09-16
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 bearkin 的回复:]

...没看明白你这个程序咋试验的
(!finishedA || !finishedB)
这个是不是应该改成
(!finishedA && !finishedB)

[/Quote]
哦,我用||的意思是,只有当两个线程都结束了,才不睡,才去打印结果值。
BearKin 2011-09-16
  • 打赏
  • 举报
回复
...没看明白你这个程序咋试验的
(!finishedA || !finishedB)
这个是不是应该改成
(!finishedA && !finishedB)
BearKin 2011-09-16
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 magong 的回复:]
引用 10 楼 bearkin 的回复:

那你可以试验一下 你看看在原始类型上如何搞出因为你没加独占锁出现的计算错误 很难的哦~


也不是很难的吧,看这个代码,很容易得到非0结果的哦

Java code

public class SimpleTest {
static int count = 0;
static boolean finishedA = ……
[/Quote]

百度搜索 伊莉莎白 是《银魂》里的神宠 比较牛逼
我在看一个文章
http://www.ibm.com/developerworks/cn/java/j-jtp06197.html我本想建议LZ用volatile关键字 但是看了之后发觉这个关键字似乎也完成不了LZ的需求 非得用独占么
softroad 2011-09-16
  • 打赏
  • 举报
回复
Integer x;
synchronized(x) {

}
magong 2011-09-16
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 bearkin 的回复:]

那你可以试验一下 你看看在原始类型上如何搞出因为你没加独占锁出现的计算错误 很难的哦~

[/Quote]
也不是很难的吧,看这个代码,很容易得到非0结果的哦

public class SimpleTest {
static int count = 0;
static boolean finishedA = false;
static boolean finishedB = false;
public static void main(String[] args) throws InterruptedException{
new Thread(){
@Override
public void run(){
for (int i=0; i< 100000; i++) count++;
finishedA = true;
}
}.start();
new Thread(){
@Override
public void run(){
for (int i=0; i< 100000; i++) count--;
finishedB = true;
}
}.start();
while (!finishedA || !finishedB) Thread.sleep(100);
System.out.println(count);
}
}


BearKin,换Logo了?是马达加斯加企鹅吗?
BearKin 2011-09-16
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 w715655775 的回复:]
引用 7 楼 bearkin 的回复:

引用楼主 w715655775 的回复:
服务器—客户机通讯问题

类Create 里有个方法,是个死循环,负责创建新的通讯线程
客户机A连接成功,创建一个新线程,专门用于和A通讯
客户机B连接成功,创建一个新线程,专门用于和B通讯

问题来了,
服务器这边某个类有个变量x,
接收到客户机A数据a则在线程里进行x+=a操作;
接收到……
[/Quote]
那你可以试验一下 你看看在原始类型上如何搞出因为你没加独占锁出现的计算错误 很难的哦~
snowjlz 2011-09-16
  • 打赏
  • 举报
回复
把X设为成员变量。
synchronized void setCount( int y){
x += y;
}
当A连接上传y=+a ;
当B连接上传y=-b;
BearKin 2011-09-16
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 magong 的回复:]
引用 14 楼 bearkin 的回复:

...没看明白你这个程序咋试验的
(!finishedA || !finishedB)
这个是不是应该改成
(!finishedA &amp;&amp; !finishedB)


哦,我用||的意思是,只有当两个线程都结束了,才不睡,才去打印结果值。
[/Quote]

看错了..
BearKin 2011-09-15
  • 打赏
  • 举报
回复
[Quote=引用楼主 w715655775 的回复:]
服务器—客户机通讯问题

类Create 里有个方法,是个死循环,负责创建新的通讯线程
客户机A连接成功,创建一个新线程,专门用于和A通讯
客户机B连接成功,创建一个新线程,专门用于和B通讯

问题来了,
服务器这边某个类有个变量x,
接收到客户机A数据a则在线程里进行x+=a操作;
接收到客户机B数据b则在线程里进行x-=b操作;
服务器同时接收到A和B的数……
[/Quote]
建议LZ补充下线程方面的知识

另外关于LZ的问题 原始类型无法使用独占锁 LZ可以锁定更新该原始类型值的函数 不过我感觉没啥必要锁定 因为基本不会出现同步问题
安心逍遥 2011-09-15
  • 打赏
  • 举报
回复
synchronized void addX( int a){
x += a;
}

贪睡的兔子 2011-09-15
  • 打赏
  • 举报
回复
只有一个变量 volatile不行吗
yosyg 2011-09-15
  • 打赏
  • 举报
回复
你只能给操作x的方法加上同步,这样效率会降低,但是也没别的办法
冰释绿茵 2011-09-15
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 bearkin 的回复:]

引用楼主 w715655775 的回复:
服务器—客户机通讯问题

类Create 里有个方法,是个死循环,负责创建新的通讯线程
客户机A连接成功,创建一个新线程,专门用于和A通讯
客户机B连接成功,创建一个新线程,专门用于和B通讯

问题来了,
服务器这边某个类有个变量x,
接收到客户机A数据a则在线程里进行x+=a操作;
接收到客户机B数据b则在线程里进行x-=b操作;
……
[/Quote]
几十台客户机和服务器交互,很容易出现问题。不锁怎么行?
baillluu 2011-09-14
  • 打赏
  • 举报
回复
你锁你操作x这个变量的类方法啊;或者锁你操作x这个那个对象。
对了,如果用后者,那这个操作x变量的这个对象,在服务器必需只有一个,或都你把那个对象声明成static !
桃园闲人 2011-09-14
  • 打赏
  • 举报
回复
如ls上所说,你只能给操作x的方法加上同步,这样效率会降低,但是也没别的办法。
magong 2011-09-14
  • 打赏
  • 举报
回复
锁方法
synchronized void addX( int a){
x += a;
}

接收到客户机A数据a则在A线程里进行addX(a)操作;
接收到客户机B数据b则在B线程里进行addX(-b)操作;

13,100

社区成员

发帖
与我相关
我的任务
社区描述
Java J2ME
社区管理员
  • J2ME社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧