大家伙儿帮忙看下,如此代码在多线程下是否能兼顾效率和稳定呢

大家帮忙看下,如此代码在多线程下是否能兼顾效率和稳定呢?
因为对多线程不熟悉。所以写了如下代码。

即多线程下 单例模式,能够高并发相应修改内容,对已修改的内容能够实时显示。不知道代码有什么问题。
isOnChanged 总觉的是多余,是吧??


private final static SpoutIntel siInstance = new  SpoutIntel();
private int spoutNowSum =0;
private volatile boolean isOnChanged =false;

private SpoutIntel(){}

public  synchronized static getInstance(){
    return  siInstance;
}

public void set(int s){
 synchronized( spoutNowSum )
 {
 isOnChanged = true;
 spoutNowSum = s;
 isOnChanged = false; 
spoutNowSum.notifyAll();
}

}

public int get(){

synchronized( spoutNowSum ){
while(isOnChanged){
spoutNowSum.wait();
}
return spoutNowSum;
}

}
 

------解决方案--------------------
spoutNowSum  这个用atom类型就可以...  不用 synchronized
------解决方案--------------------
引用:
Quote: 引用:

Quote: 引用:

Quote: 引用:

至少在这段代码里是多余的,因为isOnChanged 在get方法里永远不会是true


我是这样想的,在多线程当中使用单例模式,如果别的线程中的get与set产生了竞争条件,有没有可能正好是取数据的时候为正在修改的时候,或者高手给指点下,代码该如何修改。


get和set都在spoutNowSum 上加了锁,这里是同步操作,消除了竞争条件,一次性只有一个线程在get或set,所以不存在数据没修改完就有线程来取

额。。。这个倒是,如果set的同时,又get了,又没有wait,那么线程会不会发生阻塞呢?该如何解决?

get的时候isOnChanged不可能为true,那个wait的方法不会被执行到的,单纯要保证getset的安全,不用这个复杂,直接在方法上加synchronized就好了,其他的代码都可以去掉
------解决方案--------------------
引用:
Quote: 引用:

Quote: 引用:

Quote: 引用:

Quote: 引用:

Quote: 引用:

至少在这段代码里是多余的,因为isOnChanged 在get方法里永远不会是true


我是这样想的,在多线程当中使用单例模式,如果别的线程中的get与set产生了竞争条件,有没有可能正好是取数据的时候为正在修改的时候,或者高手给指点下,代码该如何修改。


get和set都在spoutNowSum 上加了锁,这里是同步操作,消除了竞争条件,一次性只有一个线程在get或set,所以不存在数据没修改完就有线程来取

额。。。这个倒是,如果set的同时,又get了,又没有wait,那么线程会不会发生阻塞呢?该如何解决?

get的时候isOnChanged不可能为true,那个wait的方法不会被执行到的,单纯要保证getset的安全,不用这个复杂,直接在方法上加synchronized就好了,其他的代码都可以去掉


受教了。。。仿佛明白了什么。但是如果遇到阻塞的时候会怎样,


遇到阻塞时不怎么样,效率和安全是一对矛盾体,你要保证效率就要并行,要并行就必然有安全问题;你要安全就要串行,所有逻辑全部串行就绝对安全但是牺牲效率。

所以在某些场景下,牺牲效率是没有办法的。不过好在对于一般的系统而言,性能瓶颈都不会出现在这种阻塞/不阻塞的权衡上,建议你也不要在这种问题上纠结,没有意义
------解决方案--------------------
引用:
Quote: 引用:

Quote: 引用:

Quote: 引用:

Quote: 引用:

Quote: 引用:

Quote: 引用:

Quote: 引用:

至少在这段代码里是多余的,因为isOnChanged 在get方法里永远不会是true


我是这样想的,在多线程当中使用单例模式,如果别的线程中的get与set产生了竞争条件,有没有可能正好是取数据的时候为正在修改的时候,或者高手给指点下,代码该如何修改。


get和set都在spoutNowSum 上加了锁,这里是同步操作,消除了竞争条件,一次性只有一个线程在get或set,所以不存在数据没修改完就有线程来取

额。。。这个倒是,如果set的同时,又get了,又没有wait,那么线程会不会发生阻塞呢?该如何解决?

get的时候isOnChanged不可能为true,那个wait的方法不会被执行到的,单纯要保证getset的安全,不用这个复杂,直接在方法上加synchronized就好了,其他的代码都可以去掉


受教了。。。仿佛明白了什么。但是如果遇到阻塞的时候会怎样,


遇到阻塞时不怎么样,效率和安全是一对矛盾体,你要保证效率就要并行,要并行就必然有安全问题;你要安全就要串行,所有逻辑全部串行就绝对安全但是牺牲效率。

所以在某些场景下,牺牲效率是没有办法的。不过好在对于一般的系统而言,性能瓶颈都不会出现在这种阻塞/不阻塞的权衡上,建议你也不要在这种问题上纠结,没有意义

大师受教了。。。给点学习方法和参考书籍


性能与安全这一块还是经验相关,接触得多了慢慢就比较熟悉了