开发者社区> 我哩个去> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

Synchronized相关

简介:
+关注继续查看

synchronized的说明

一、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。

二、然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。

三、尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。

四、第三个例子同样适用其它同步代码块。也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。

五、以上规则对其它对象锁同样适用.

synchronized与static synchronized区别

说明

synchronized是对类的当前实例进行加锁,防止其他线程同时访问该类的该实例的所有synchronized块,注意这里是“类的当前实例”,类的两个不同实例就没有这种约束了。

那么static synchronized恰好就是要控制类的所有实例的访问了,static synchronized是限制线程同时访问jvm中该类的所有实例同时访问对应的代码块。

实际上,如果在类中某方法或某代码块中有 synchronized,那么在生成一个该类实例后,该类也就有一个监视块,监视线程并发访问改实例synchronized保护块。而static synchronized则是该类的所有实例公用一个监视块,这便是两个的区别了。

也就是synchronized相当于 this.synchronized,而static synchronized相当于Something.synchronized.

结论:

A: synchronized static是某个类的范围,synchronized static cSync{}防止多个线程同时访问这个类中的synchronized static 方法。它可以对类的所有对象实例起作用。

B: synchronized 是某实例的范围,synchronized isSync(){}防止多个线程同时访问这个实例中的synchronized 方法。

例程

例如下面函数,创建了20个线程,每个线程都对race进行100000次累加,加static和不加static的increase函数,将会得到不同的结果。

例程一

对于不加static 参数的increase() 函数,如果在同一个实例中调用,将能得到预期的结果(最终输出的race都会等于200000):

</pre>
<pre>package chapter12;
class TestStatic {
 public static volatile int race = 0;
 public synchronized void increase() {
 race ++ ;
 }
}
public class StaticTest {
 public static void main(String[] args) {
 final TestStatic test = new TestStatic();
 Thread[] threads = new Thread[20];
 for(int i=0 ; i<20 ;i++) {
 threads[i] = new Thread(new Runnable(){
 @Override
 public void run() {
 for(int j = 0 ; j<100000 ; j++) {
 test.increase();
 }
 }
 });
 threads[i].start();
 }
 while(Thread.activeCount()>1) {
 Thread.yield();
 }
 System.out.println(TestStatic.race);
 }
}</pre>
<pre>

例程二

对于不加static 参数的increase() 函数,如果在多个实例中调用,将不能得到预期的结果(最终输出的race都会小于200000):

package chapter12;
class TestStatic {
    public static volatile int race = 0;
    public synchronized void increase() {
        race ++ ;
    }
}
public class StaticTest {
    public static void main(String[] args) {
        Thread[] threads = new Thread[20];
        for(int i=0 ; i<20 ;i++) {
            threads[i] = new Thread(new Runnable(){
                TestStatic test = new TestStatic();
                @Override
                public void run() {
                    for(int j = 0 ; j<100000 ; j++) {
                        test.increase();
                    }
                }
            });
            threads[i].start();
        }
        while(Thread.activeCount()>1) {
            Thread.yield();
        }
        System.out.println(TestStatic.race);
    }
}

例程三

对于加上了static 参数的increase() 函数,不管是在多个实例中、还是在同一个实例中被调用,将都能得到预期的结果(最终输出的race都会
package chapter12;
class TestStatic {
    public static volatile int race = 0;
    public static synchronized void increase() {
        race ++ ;
    }
}
public class StaticTest {
    public static void main(String[] args) {
//      final TestStatic test = new TestStatic();
        Thread[] threads = new Thread[20];
        for(int i=0 ; i<20 ;i++) {
            threads[i] = new Thread(new Runnable(){
                TestStatic test = new TestStatic();
                @Override
                public void run() {
                    for(int j = 0 ; j<100000 ; j++) {
                        test.increase();
                    }
                }
            });
            threads[i].start();
        }
        while(Thread.activeCount()>1) {
            Thread.yield();
        }
        System.out.println(TestStatic.race);
    }
}

题目

(一个日本作者-结成浩的《java多线程设计模式》有这样的一个列子:

pulbic class Something(){

public synchronized void isSyncA(){}

public synchronized void isSyncB(){}

public static synchronized void cSyncA(){}

public static synchronized void cSyncB(){}

}

那么,加入有Something类的两个实例a与b,那么下列组方法可以被1个以上线程同时访问呢

a.   x.isSyncA()与x.isSyncB()

b.   x.isSyncA()与y.isSyncA()

c.   x.cSyncA()与y.cSyncB()

d.   x.isSyncA()与Something.cSyncA()

这里,很清楚的可以判断:

a,都是对同一个实例的synchronized域访问,因此不能被同时访问

b,是针对不同实例的,因此可以同时被访问

c,因为是static synchronized,所以不同实例之间仍然会被限制,相当于Something.isSyncA()与   Something.isSyncB()了,因此不能被同时访问。

d,书上的答案是可以被同时访问的,答案理由是synchronzied的是实例方法与synchronzied的类方法由于锁定(lock)不同的原因。

个人分析也就是synchronized 与static synchronized 相当于两帮派,各自管各自,相互之间就无约束了,可以被同时访问。目前还不是分清楚java内部设计synchronzied是怎么样实现的。)

synchronized方法与synchronized代码块的区别

synchronized methods(){} 与synchronized(this){}之间没有什么区别,只是 synchronized methods(){} 便于阅读理解。

而synchronized(this){}可以更精确的控制冲突限制访问区域,有时候表现更高效率, 它的作用域是当前对象。

synchronized关键字是不能继承的

继承时子类的覆盖方法必须显示定义成synchronized。

也就是说,基类的方法synchronized f(){} 在继承类中并不自动是synchronized f(){},而是变成了f(){}。继承类需要你显式的指定它的某个方法为synchronized方法


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Synchronized原理
我们最初学习Java的时候,遇到多线程我们会知道synchronized,对于当时的我们来说synchronized是保证了多线程之间的同步,也成为了我们解决多线程情况的常用手段。但是,随着我们学习的进行我们知道synchronized是一个重量级锁,相对于Lock,它会显得那么笨重,以至于我们认为它不是那么的高效而慢慢摒弃它。
7 0
synchronized学习
synchronized 简介 synchronized是Java中的关键字,是一种同步锁。它修饰的对象有以下几种:   1. 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象;   2. 修饰一个方法,被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象;   3. 修改一个静态的方法,其作用的范围是整个静态方法,作用的对象是这个类的所有对象;   4. 修改一个类,其作用的范围是synchronized后面括号括起来的部分,作用主的对象是这个类的所有对象。
33 0
Synchronized与Lock的区别与应用场景
Synchronized与Lock的区别与应用场景
104 0
Synchronized 天天用,实现原理你懂吗?
Synchronized 天天用,实现原理你懂吗?
26 0
synchronized猎奇
### 阶段1 事情的起因是同事写了这样一段代码。 ``` @synchronized(@"test synchronized"){ NSLog(@"do something"); } ``` 于是我指出这样应该是锁不住的,因为 synchronized 锁的是对象,而每次创建的字符串都是新对象,所以锁不住。 同事跟我说,“no,no,no”,你太天真了,编
1592 0
synchronized关键字
首先,我们简单总结一下锁对象(Lock)和条件对象(Condition)的要点: 锁用来保护代码片段,任何时刻只能有一个线程执行被保护的代码 锁可以管理试图进入被保护代码段的线程 锁可以拥有一个或多个相关的条件对象 每个条件对象管理那些已经进入被保护的代码段但还不能运行的线程 其实大多数情况下,我们并不需要像 Lock 和 Condition 那样高度的锁定控制,synchronized 关键字就是 Java 提供一种简洁的锁定控制方式。
939 0
synchronized的理解
用法解释 synchronized是Java中的关键字,是一种同步锁。它修饰的对象有以下几种: 1. 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象; 2. 修饰一个方法,被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象; 3. 修饰一个静态的方法,其作用的范围是整个静态方法,作用的对象是这个类的所有对象; 4. 修饰一个类(Person.class),其作用的范围是synchronized后面括号括起来的部分,作用的对象是这个类的所有对象。
774 0
多线程之:lock和synchronized的区别
多次思考过这个问题,都没有形成理论,今天有时间了,我把他总结出来,希望对大家有所帮助     1、ReentrantLock 拥有Synchronized相同的并发性和内存语义,此外还多了 锁投票,定时锁等候和中断锁等候      线程A和B都要获取对象O的锁定,假设A获取了对象O锁,B将等...
1762 0
+关注
15
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载