我对synchronized关键字的用法和重要性有一些疑问.
synchronized关键字有什么意义?synchronized?任何人都可以通过一个例子告诉我同步方法优于synchronized块的优势吗?
每当有关Java同步的问题出现时,有些人非常渴望指出synchronized(this)应该避免的.相反,他们声称,首选锁定私人参考.
一些给出的原因是:
其他人,包括我在内,认为这synchronized(this)是一个被大量使用的习惯用法(也在Java库中),是安全且易于理解的.它不应该被避免,因为你有一个错误,你不知道多线程程序中发生了什么.换句话说:如果适用,则使用它.
我有兴趣看到一些现实世界的例子(没有foobar的东西)避免锁定this是最好的,当synchronized(this)也做的工作.
因此:您是否应始终避免synchronized(this)并使用私有引用上的锁来替换它?
一些进一步的信息(更新为答案):
synchronized方法)和显式形式synchronized(this)synchronized(this)提供,那么synchronized(this)不适用,所以这不是问题我想知道在声明变量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 8中,我可以轻松地写:
interface Interface1 {
default void method1() {
synchronized (this) {
// Something
}
}
static void method2() {
synchronized (Interface1.class) {
// Something
}
}
}
Run Code Online (Sandbox Code Playgroud)
我将获得完全同步语义,我也可以在类中使用.但是,我不能synchronized在方法声明上使用修饰符:
interface Interface2 {
default synchronized void method1() {
// ^^^^^^^^^^^^ Modifier 'synchronized' not allowed here
}
static synchronized void method2() {
// ^^^^^^^^^^^^ Modifier 'synchronized' not allowed here
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我们可以认为,这两个接口的行为方式相同,只是Interface2建立了一个合同上的method1()和method2(),这是比强一点Interface1呢.当然,我们也可能会争辩说default实现不应该对具体实现状态做出任何假设,或者这样的关键字根本不会减轻它的重量.
JSR-335专家组决定不支持synchronized接口方法的原因是什么?
如果我在同一个类中有2个同步方法,但每个方法访问不同的变量,那么2个线程可以同时访问这两个方法吗?锁是否发生在对象上,或者它是否与synchronized方法中的变量一样具体?
例:
class X {
private int a;
private int b;
public synchronized void addA(){
a++;
}
public synchronized void addB(){
b++;
}
}
Run Code Online (Sandbox Code Playgroud)
2个线程可以同时访问同一个X类实例x.addA()x.addB()吗?
Java教程说:"同一个对象上的两个同步方法的调用不可能交错."
这对静态方法意味着什么?由于静态方法没有关联对象,所以synchronized关键字会锁定类,而不是对象吗?
如果我在同一个类上同步两个方法,它们可以同时在同一个对象上运行吗?例如:
class A {
public synchronized void methodA() {
//method A
}
public synchronized void methodB() {
// method B
}
}
Run Code Online (Sandbox Code Playgroud)
我知道我不能methodA()在两个不同的线程中对同一个对象运行两次.同样的事情methodB().
但是,在运行methodB()时我可以在不同的线程上methodA()运行吗?(同一个对象)
这个java代码是什么意思?它会锁定所有物体MyClass吗?
synchronized(MyClass.class) {
//is all objects of MyClass are thread-safe now ??
}
Run Code Online (Sandbox Code Playgroud)
以上代码与此不同:
synchronized(this) {
//is all objects of MyClass are thread-safe now ??
}
Run Code Online (Sandbox Code Playgroud) 每次在非最终类字段上同步时都会显示警告.这是代码:
public class X
{
private Object o;
public void setO(Object o)
{
this.o = o;
}
public void x()
{
synchronized (o) // synchronization on a non-final field
{
}
}
}
Run Code Online (Sandbox Code Playgroud)
所以我用以下方式改变了编码
public class X
{
private final Object o;
public X()
{
o = new Object();
}
public void x()
{
synchronized (o)
{
}
}
}
Run Code Online (Sandbox Code Playgroud)
我不确定上面的代码是在非final类字段上同步的正确方法.如何同步非最终字段?
java ×10
synchronized ×10
locking ×3
class ×1
concurrency ×1
java-8 ×1
java-me ×1
java-threads ×1
jsr335 ×1
keyword ×1
methods ×1
static ×1
volatile ×1