我有一个类,里面存储着一些 static 的变量,在整个程序中这些变量的值会变化,类似于这样:
class Foo {
public static int FOO = 0;
}
这个 FOO 类里的变量 FOO 我会在 Service 里读取他,但是同时也有可能会被一些 activity 里的回调函数修改。service 有时候不能实时读取这个被修改的值,我现在的实现就是这样,让这个类可以被所有人访问修改,谁要用这个数值谁就去读,但是就像刚才说的,也许我想要的值会在我读取之后才被修改,造成了滞后。请问应该怎么解决呢?还是我这样的用法时大错特错的。
1
11wangyaoda 2019-01-09 20:13:43 +08:00
关键词。atomic volatile concurrency.
|
2
ho121 2019-01-09 20:17:27 +08:00 via Android
可能 service 和 activity 没有在一个进程中
|
3
codechaser OP @11wangyaoda 你好, 这个好像和原子性没啥关系吧?我这个变量在整个应用运行过程中都有可能被修改。
|
4
codechaser OP @ho121 service 和 activity 都是同一个应用
|
5
guotao2beijing 2019-01-09 20:36:28 +08:00
应该不是滞后,你可以修改 F00 的值以后直接打印出来看看有没有修改。
猜测是 service 在启动的时候就把 F00 的值持有在栈内存里了,而你改 F00 的值是改动堆内存里的数据,service 不知道。 |
6
symeonchen 2019-01-09 20:37:22 +08:00 via Android
取决于你的具体场景,不谈多进程的前提下,数据能被各处获取->单例 /持久化 /etc.;数据被操作的一段时间内禁止修改->加锁;数据的变化实时同步到各处->回调 /通知
|
7
kx5d62Jn1J9MjoXP 2019-01-09 20:38:07 +08:00 via Android
使用观察者模式:
对于需要接收最新值的 service,subscribe 一下 每次对这个值进行改动的时候,通知所有的 subscriber |
8
Icezers 2019-01-09 20:39:48 +08:00 via iPhone
@codechaser 同一个应用不一定是同一个进程
|
9
frienmo 2019-01-09 23:36:04 +08:00
@Icezers 不好意思杠一下,应该是线程 thread 吧。同一个 app(jvm)了,一定是同一个进程 process 吧。
|
10
crayygy 2019-01-09 23:40:48 +08:00 via iPhone
@frienmo 不一定的,进程可以有多个,取决于实现,只是一般进程通信没有线程那么方便所以这么用的不多。
|
11
rosu 2019-01-09 23:51:38 +08:00 via Android
对值的读写顺序,应该只能通过程序逻辑来保证了。
在语法方面应该不存在先修改,并且可多次修改后再读取。 1. 要么像楼上那样,把这个变量用一个订阅改写成可订阅式,当被修改就通知订阅者( Service ),后者用标志变量来确认该值的修改状态?但是这样也不十分符合你的需求。也需要程序逻辑来保证。 2. 如果是一次修改,之后不再对该变量执行写操作,可以用 kotlin 里的 by...lazy 来延迟初始化。 |
12
wolegequ 2019-01-10 00:42:44 +08:00 via Android
修改的时候打日志。btw 是通过 setter 修改的吗?
|
13
codechaser OP @guotao2beijing 静态变量不是一直存在静态存储区吗?就是说我每次都得主动更新值是吗
|
14
ho121 2019-01-10 09:13:56 +08:00 via Android
@codechaser 简单的场景,service 改了值,然后进程被杀掉了,你再打开 activity,static 变量又被重新初始化一遍
|
15
codechaser OP @ho121 是这样的,所以我现在只考虑应用运行过程中就行了😂
|
16
stuazt 2019-01-10 10:18:47 +08:00
LiveData/MutableLiveData 了解一下,官方 Android Architecture Components 的一个库。
|
17
brucewuio 2019-01-10 14:06:32 +08:00
重新学 java
|
18
codechaser OP @brucewuio 学哪个部分?我马上去看
|
19
siyehua 2019-01-10 22:31:41 +08:00
@codechaser
首先哪怕是同一个应用,也可以是不同的进程。 其次,楼主表达的非常不清晰:到底是要每次去读 /写的时候,取的值一定是最新的,还是怎么样,从楼主题目上说的不是很清楚。 然后,就算整个应用都可以访问,也可以做成私有的,然后使用方法来 get/set,这样无论是添加监听,或者是添加同步方法,都要容易得多。 最后,如果这个变量有比较多的地方用到,且涉及到多线程 /进程,而且变化比较复杂。比如说这个值的写入,必须依赖其他地方的值(楼主说的滞后问题),那我建议使用同步方法修饰 set/get。如果写入不需要依赖,则可以使用 volatile |
20
nicevar 2019-01-13 11:12:53 +08:00
@frienmo 同一个应用不一定是同一个进程,你在 service 的 process 属性里面配置 remote 就是在不同的进程了。这种情况是不能通过静态变量共享的。
楼主的表达不够清晰,不过你的想法也是有点问题,你这种情形为什么不用 android 的 SharePreference 呢?很多人在使用静态变量的时候会犯两个错误,一个是不初始化,另一个就是跨进程访问。 |
21
codechaser OP @nicevar 那些变量是随时要用的,所以我没考虑用 sharedpreference
|