使用synchronized锁实现线程同步

为什么要用线程同步

我们先来看下这段代码的运行结果:

Java学习交流群:495273252

在多线程上篇博客已经介绍过了,JVM采用的是抢占式调度模型,当一个线程sleep的时候,其它线程会抢占CPU资源。如果发生在数据库中,就是“脏读”。synchronized锁就是用来解决这个问题的,多线程的线程同步机制实际上是靠锁的概念来控制的。

第一种方式:synchronized关键字修饰函数方法

Java学习交流群:495273252

第二种方式:synchronized关键字修饰代码块

Java学习交流群:495273252

多个对象多个锁的情况

三个线程同时进行,每个线程只打印一个字母,交替打印ABCABC...

Java学习交流群:495273252

prev代表前一个对象,self代表自身。线程先持有前一个对象的锁和本次要打印的对象的锁,执行打印,然后唤醒一个正在等待当前对象锁的线程(剩下的那个线程),并让它拿到对象锁。prev.wait()方法让本线程进入等待状态,让本线程休眠,线程自动释放其占有的对象锁,并等待notify。如此循环反复打印8次ABC。

总结一下

  1. 当多个线程访问同一对象的时候,只能有一个线程取得对象的锁,多个对象需要多个对象的锁。

  2. 哪个线程执行了带synchronized关键字的方法,哪个线程就持有该方法所属对象的锁,其他的线程要访问这个对象锁内的内容,都只能等待这个锁被释放后,再去抢占资源获得对象的锁。

  3. synchronized修饰非static的方法时,锁的就是对象本身,也就是this。

  4. synchronized修饰static的方法时,方法中无法使用this,所以它锁的不是this,而是这个类。所以,static synchronized方法也相当于全局锁。

  5. 使用synchronized关键字,应尽量缩小代码块的范围,最好能在代码块上加同步,而不是在整个方法上加同步。因为你锁的范围大的话,时间又长,别的线程就不会获得相应的资源。

A线程持有对象的锁,B线程可以以异步方式调用对象中的非synchronized同步的方法。

java多线程(四)的更多相关文章

  1. java 多线程四

    java 多线程一 java 多线程二 java 多线程三 java 多线程四 一个生产者,消费者的例子: import java.util.Stack; /** * Created by root ...

  2. java多线程(四)-自定义线程池

    当我们使用 线程池的时候,可以使用 newCachedThreadPool()或者 newFixedThreadPool(int)等方法,其实我们深入到这些方法里面,就可以看到它们的是实现方式是这样的 ...

  3. Java多线程(四) 线程池

    一个优秀的软件不会随意的创建.销毁线程,因为创建和销毁线程需要耗费大量的CPU时间以及需要和内存做出大量的交互.因此JDK5提出了使用线程池,让程序员把更多的精力放在业务逻辑上面,弱化对线程的开闭管理 ...

  4. java多线程四种实现模板

    假设一个项目拥有三块独立代码块,需要执行,什么时候用多线程? 这些代码块某些时候需要同时运行,彼此独立,那么需要用到多线程操作更快... 这里把模板放在这里,需要用的时候寻找合适的来选用. 总体分为两 ...

  5. Java多线程(四) —— 线程并发库之Atomic

    一.从原子操作开始 从相对简单的Atomic入手(java.util.concurrent是基于Queue的并发包,而Queue,很多情况下使用到了Atomic操作,因此首先从这里开始). 很多情况下 ...

  6. java多线程(四)之同步机制

    1.同步的前提 多个线程 多个线程使用的是同一个锁 2.同步的好处 同步的出现解决了多线程的安全问题 3.同步的弊端 当线程较多时, 因为每个线程都会去判断同步上的锁, 这样是很耗费资源的, 会降低程 ...

  7. java多线程(四)

    一个例子: Account.java 客户实体类 package com.asiainfo.test.thread8; /** * 账户类 * @author luke * */ public cla ...

  8. JAVA多线程(四) Executor并发框架向RabbitMQ推送消息

    github代码地址: https://github.com/showkawa/springBoot_2017/tree/master/spb-demo/spb-brian-query-service ...

  9. Java多线程——<四>让线程有返回值

    一.概述 到目前为止,我们已经能够声明并使一个线程任务运行起来了.但是遇到一个问题:现在定义的任务都没有任何返回值,那么加入我们希望一个任务运行结束后告诉我一个结果,该结果表名任务执行成功或失败,此时 ...

  10. Java多线程——<八>多线程其他概念

    一.概述 到第八节,就把多线程基本的概念都说完了.把前面的所有文章加连接在此: Java多线程——<一>概述.定义任务 Java多线程——<二>将任务交给线程,线程声明及启动 ...

随机推荐

  1. 【java】java 设计模式(4):建造者模式(Builder)

    工厂类模式提供的是创建单个类的模式,而建造者模式则是将各种产品集中起来进行管理,用来创建复合对象,所谓复合对象就是指某个类具有不同的属性,其实建造者模式就是前面抽象工厂模式和最后的Test结合起来得到 ...

  2. zoj 1022 - Parallel Expectations

    题目:有两个指令序列,在执行时,能够执行随意指令序列的下一条指令.每条指令要一直执行到结束. 求两组指令执行结束后,每一个变量里面存储值的期望. 分析:dp,模拟.这道题算不上难题,只是算得上的麻烦题 ...

  3. POJ 3093 Margaritas(Kind of wine) on the River Walk (背包方案统计)

    题目 Description One of the more popular activities in San Antonio is to enjoy margaritas in the park ...

  4. Dubbo(一) -- 初体验

    Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,是阿里巴巴SOA服务化治理方案的核心框架. 一.Dubbo出现的背景 随着互联网的发展,网站应用的规模不断扩大,常规的 ...

  5. [直观学习排序算法] 视觉直观感受若干常用排序算法 以及 iOS 资料

    http://www.zhfish.net/?s=点击范围 1 快速排序 介绍: 快速排序是由东尼·霍尔所发展的一种排序算法.在平均状况下,排序 n 个项目要Ο(n log n)次比较.在最坏状况下则 ...

  6. 《C++ Primer Plus》第15章 友元、异常和其他 学习笔记

    友元使得能够为类开发更灵活的接口.类可以将其他函数.其他类和其他类的成员函数作为友元.在某些情况下,可能需要前向声明,需要特别注意类和方法声明的顺序,以正确地组合友元.潜逃类是在其他类中生命的类,它有 ...

  7. 互斥锁mutex

    https://blog.csdn.net/rqc112233/article/details/50015069 //g++ mute.cpp -o mute -g -lrt -lpthread #i ...

  8. RDO部署多节点OpenStack Havana(OVS+GRE)

    RDO是由红帽RedHat公司推出的部署OpenStack集群的一个基于Puppet的部署工具,可以很快地通过RDO部署一套复杂的OpenStack环境,当前的RDO默认情况下,使用Neutron进行 ...

  9. 您需要安装旧 Java SE 6 运行环境才能打开“Eclipse”。

    mac删除jdk: sudo rm -rf /Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk 旧版本sdk地址: http://www.oracle. ...

  10. SVN常见问题及解决方法(转载)

    svn常见符号 黄色感叹号(有冲突):--这是有冲突了,冲突就是说你对某个文件进行了修改,别人也对这个文件进行了修改,别人抢在你提交之前先提交了,这时你再提交就会被提示发生冲突,而不允许你提交,防止你 ...