所以我们在用synchronized关键字的时候,能缩小代码段的范围就尽量缩小,能在代码段上加同步就不要再整个方法上加同步。这叫减小锁的粒度,使代码更大程度的并发。原因是基于以上的思想,锁的代码段太长了,别的线程是不是要等很久,等的花儿都谢了。当然这段是题外话,与本文核心思想并无太大关联。

  再看上面的代码,每个线程中都new了一个Sync类的对象,也就是产生了三个Sync对象,由于不是同一个对象,所以可以多线程同时运行synchronized方法或代码段。

  为了验证上述的观点,修改一下代码,让三个线程使用同一个Sync的对象。

class MyThread extends Thread {

private Sync sync;

public MyThread(Sync sync) {   this.sync = sync;  }

public void run() {   sync.test();  } }

public class Main {

public static void main(String[] args) {   Sync sync = new Sync();   for (int i = 0; i < 3; i++) {    Thread thread = new MyThread(sync);    thread.start();   }  } }

  运行结果:

  test开始..   test结束..   test开始..   test结束..   test开始..   test结束..

  可以看到,此时的synchronized方法和synchronized代码段就都起了作用。

  那么,如果真的想锁住这段代码,要怎么做?也就是,如果还是最开始的那段代码,每个线程new一个Sync对象,怎么才能让test方法不会被多线程执行。

  解决也很简单,只要锁住同一个对象不就行了。例如,synchronized后的括号中锁一个static final对象,这样就行了。这样是没问题,但是,比较多的做法是让synchronized锁这个类对应的Class对象。

class Sync {

public void test() {   synchronized (Sync.class) {    System.out.println("test开始..");    try {     Thread.sleep(1000);    } catch (InterruptedException e) {     e.printStackTrace();    }    System.out.println("test结束..");   }  } }

class MyThread extends Thread {

public void run() {   Sync sync = new Sync();   sync.test();  } }

public class Main {

public static void main(String[] args) {   for (int i = 0; i < 3; i++) {    Thread thread = new MyThread();    thread.start();   }  } }

  运行结果:

  test开始..   test结束..   test开始..   test结束..   test开始..   test结束..

  上面代码用synchronized(Sync.class)实现了全局锁的效果。

  最后说说static synchronized,实际上static方法可以直接类名加方法名调用,方法里面没有this这个概念,所以,static synchronized方法也相当于全局锁,相当于锁住了代码段。

Java线程同步:synchronized锁住的是代码还是对象的更多相关文章

  1. synchronized锁住的是代码还是对象

    不同的对象 public class Sync { public synchronized void test() { System.out.println("test start" ...

  2. synchronized锁住的是代码还是对象,以及synchronized底层实现原理

    synchronized (this)原理:涉及两条指令:monitorenter,monitorexit:再说同步方法,从同步方法反编译的结果来看,方法的同步并没有通过指令monitorenter和 ...

  3. Java并发,synchronized锁住的内容

    synchronized用在方法上锁住的是什么? 锁住的是当前对象的当前方法,会使得其他线程访问该对象的synchronized方法或者代码块阻塞,但并不会阻塞非synchronized方法. 脏读 ...

  4. Java线程同步与锁

    一.synchronized synchronized锁什么?锁对象.可能锁对象包括: this, 临界资源对象,Class类对象. 1,同步方法 synchronized T methodName( ...

  5. Java线程同步synchronized的理解

    JVM中(留神:马上讲到的这两个存储区只在JVM内部与物理存储区无关)存在一个主内存(Main Memory),Java中所有的变量存储在主内存中,所有实例和实例的字段都在此区域,对于所有的线程是共享 ...

  6. Java线程(二):线程同步synchronized和volatile

    上篇通过一个简单的例子说明了线程安全与不安全,在例子中不安全的情况下输出的结果恰好是逐个递增的(其实是巧合,多运行几次,会产生不同的输出结果),为什么会产生这样的结果呢,因为建立的Count对象是线程 ...

  7. Java提高班(三)并发中的线程同步与锁

    乐观锁.悲观锁.公平锁.自旋锁.偏向锁.轻量级锁.重量级锁.锁膨胀...难理解?不存的!来,话不多说,带你飙车. 上一篇介绍了线程池的使用,在享受线程池带给我们的性能优势之外,似乎也带来了另一个问题: ...

  8. Java并发包——线程同步和锁

    Java并发包——线程同步和锁 摘要:本文主要学习了Java并发包里有关线程同步的类和锁的一些相关概念. 部分内容来自以下博客: https://www.cnblogs.com/dolphin0520 ...

  9. Java多线程-同步:synchronized 和线程通信:生产者消费者模式

    大家伙周末愉快,小乐又来给大家献上技术大餐.上次是说到了Java多线程的创建和状态|乐字节,接下来,我们再来接着说Java多线程-同步:synchronized 和线程通信:生产者消费者模式. 一.同 ...

随机推荐

  1. java5初学

    1.Eclipse快捷键 alt + / 代码提示,例如自动创建main方法ctrl + d 删除当前行ctrl + alt + up/down 复制当前行alt + up/down 交换行ctrl ...

  2. python学习_循环结构 and 类型判断

    # 循环结构 ### 循环结构(while) - 格式 ```python while 表达式: 语句块 ``` > 执行流程:当程序执行到while语句时,首先判断表达式的真假.若表达式的值为 ...

  3. (原)Unreal渲染模块 管线 - 着色器(1)

    @author: 白袍小道 转载悄悄说明下 随缘查看,施主开心就好 说明: 本篇继续Unreal搬山部分的渲染模块的Shader部分, 主要牵扯模块RenderCore, ShaderCore, RH ...

  4. CMake Tutorial & Example

    Tutorial CMakeLists用于告诉CMake我们要对这个目录下的文件做什么事情 cmake 的特点主要有: 1,开放源代码,使用类 BSD 许可发布.http://cmake.org/HT ...

  5. CSU-2214 Sequence Magic

    题目链接 http://acm.csu.edu.cn:20080/csuoj/problemset/problem?pid=2214 题目 Description 有一个1到N的自然数序列1,2,3, ...

  6. php中各种操作字符串和时间戳的代码关键词

    <?php/** * Created by 郭鹏. * User: msi * Date: 2017/9/27 * Time: 14:17 */ //随机数生成器echo rand();echo ...

  7. 软工实践 - 第十七次作业 Alpha 冲刺 (8/10)

    队名:起床一起肝活队 组长博客:https://www.cnblogs.com/dawnduck/articles/10023469.html 作业博客:班级博客本次作业的链接 组员情况 组员1(队长 ...

  8. HTML快速入门

    我们经常上网浏览网页,来获取资讯.可网页是什么呢?它又是如何编写出来的呢? 网页又叫Web页面,我们经常可以在网页上看到文字.图片.视频等.我们所要说的HTML(超文本标记语言)就是构成网页文档的主要 ...

  9. oracle怎么查看一个表或一个索引占用多少空间

    很多时候我们想知道一个表或一个索引占用多少M的空间,以下脚本就是满足这个要求的,记住替换其中的内容. SELECT owner, segment_name, SUM(bytes)/1024/1024 ...

  10. mvvm实现

    https://segmentfault.com/a/1190000006599500 http://blog.csdn.net/pur_e/article/details/53066275