我对synchronized关键字的用法和重要性有一些疑问.
synchronized关键字有什么意义?synchronized?我想知道在声明变量as volatile和始终访问synchronized(this)Java 中的块中的变量之间的区别?
根据这篇文章,http://www.javamex.com/tutorials/synchronization_volatile.shtml有很多要说的,但也有很多不同之处,但也有一些相似之处.
我对这条信息特别感兴趣:
...
- 对volatile变量的访问永远不会阻塞:我们只进行简单的读或写操作,因此与synchronized块不同,我们永远不会持有任何锁;
- 因为访问volatile变量永远不会持有锁,所以它不适合我们想要读取update-write作为原子操作的情况(除非我们准备"错过更新");
read-update-write是什么意思?写入也不是更新,还是仅仅意味着更新是依赖于读取的写入?
最重要的是,何时更适合声明变量volatile而不是通过synchronized块访问变量?使用volatile依赖于输入的变量是一个好主意吗?例如,有一个变量被称为render通过渲染循环读取并由按键事件设置?
我读过" 什么时候在Java中使用'volatile'? "但我仍然感到困惑.我怎么知道何时应该标记变量volatile?如果我弄错了,要么在需要它的东西上省略volatile,要么在不需要的东西上放置volatile呢?在确定多线程代码中哪些变量应该是易变的时,有哪些经验法则?
我经常发现这些术语在并发编程的上下文中使用.它们是相同的还是不同的?
我有一个从a获取对象的类,BlockingQueue并通过take()在连续循环中调用来处理它们.在某些时候,我知道不会有更多的对象被添加到队列中.如何中断该take()方法以阻止其阻塞?
这是处理对象的类:
public class MyObjHandler implements Runnable {
private final BlockingQueue<MyObj> queue;
public class MyObjHandler(BlockingQueue queue) {
this.queue = queue;
}
public void run() {
try {
while (true) {
MyObj obj = queue.take();
// process obj here
// ...
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是使用此类处理对象的方法:
public void testHandler() {
BlockingQueue<MyObj> queue = new ArrayBlockingQueue<MyObj>(100);
MyObjectHandler handler = new MyObjectHandler(queue);
new Thread(handler).start();
// get objects for handler to process …Run Code Online (Sandbox Code Playgroud) java内存模型强制要求写一个int是原子的:也就是说,如果你在一个线程中写一个值(由4个字节组成)并在另一个线程中读取它,你将获得所有字节或没有,但永远不会有2个新字节和2个旧字节或类似的.
这不保证long.在这里,写入之前0x1122334455667788保存的变量0可能导致另一个线程读取0x112233440000000或0x0000000055667788.
现在,规范并未强制对象引用为int或long.出于类型安全的原因,我怀疑它们是保证以原子方式编写的,但在64位VM上,这些引用可能是非常好的64位值(仅仅是内存地址).
现在我的问题是:
此致,斯蒂芬
所以在android中我想让我的应用程序类成为单例.
像这样:
object MyApplication: Application(){}
Run Code Online (Sandbox Code Playgroud)
不行.在运行时抛出以下错误:
java.lang.IllegalAccessException: private com....is not accessible from class android.app.Instrumentation.
Run Code Online (Sandbox Code Playgroud)
这样做也是不可能的:
class MyApp: Application() {
private val instance_: MyApp
init{
instance_ = this
}
override fun onCreate() {
super.onCreate()
if (BuildConfig.DEBUG) {
Timber.plant(Timber.DebugTree());
}
}
companion object{
fun getInstance() = instance_
}
}
Run Code Online (Sandbox Code Playgroud)
那么如何才能在我的应用程序中随处获得应用程序类的实例,MyApp.instance()而不是使用(applicationContext as MyApp).
还解释了为什么我想要这个:我在我的应用程序中有类,例如,使用上下文初始化的SharedPreference Singleton,并且作为它的单例,不能有参数.
关于我在java中读取volatile关键字的应用,我真的很困惑.
以下陈述是否正确?"在对同一字段的每次后续读取之前发生对易失性字段的写入"
理想情况下应该使用volatile关键字吗?
有什么区别:
class TestClass
{ private int x;
synchronized int get(){return x;}
synchronized void set(int x){this.x = x;}
}
Run Code Online (Sandbox Code Playgroud)和
class TestClass
{ private volatile int x;
int get(){return x;}
void set(int x){this.x = x;}
}
Run Code Online (Sandbox Code Playgroud) 年复一年,我试图了解部分与内存模型和并发交易的Java规范.我不得不承认我惨遭失败.是的'我理解锁和"synchronized"以及wait()和notify().我可以使用它们,谢谢.我甚至对"易变"的含义有一个模糊的想法.但所有这些都不是来自语言规范 - 而是来自一般经验.
以下是我要问的两个示例问题.我对特定答案并不是那么感兴趣,因为我需要理解答案是如何从规范中得出的(或者可能是我如何得出规范没有答案).
java ×8
concurrency ×3
volatile ×3
synchronized ×2
android ×1
atomic ×1
blocking ×1
data-race ×1
interrupt ×1
java-me ×1
keyword ×1
kotlin ×1
memory-model ×1
reference ×1
singleton ×1