java多线程(四)
使用synchronized锁实现线程同步
为什么要用线程同步
我们先来看下这段代码的运行结果:
Java学习交流群:495273252
在多线程上篇博客已经介绍过了,JVM采用的是抢占式调度模型,当一个线程sleep的时候,其它线程会抢占CPU资源。如果发生在数据库中,就是“脏读”。synchronized锁就是用来解决这个问题的,多线程的线程同步机制实际上是靠锁的概念来控制的。
第一种方式:synchronized关键字修饰函数方法
Java学习交流群:495273252
第二种方式:synchronized关键字修饰代码块
Java学习交流群:495273252
多个对象多个锁的情况
三个线程同时进行,每个线程只打印一个字母,交替打印ABCABC...
Java学习交流群:495273252
prev代表前一个对象,self代表自身。线程先持有前一个对象的锁和本次要打印的对象的锁,执行打印,然后唤醒一个正在等待当前对象锁的线程(剩下的那个线程),并让它拿到对象锁。prev.wait()方法让本线程进入等待状态,让本线程休眠,线程自动释放其占有的对象锁,并等待notify。如此循环反复打印8次ABC。
总结一下
当多个线程访问同一对象的时候,只能有一个线程取得对象的锁,多个对象需要多个对象的锁。
哪个线程执行了带synchronized关键字的方法,哪个线程就持有该方法所属对象的锁,其他的线程要访问这个对象锁内的内容,都只能等待这个锁被释放后,再去抢占资源获得对象的锁。
synchronized修饰非static的方法时,锁的就是对象本身,也就是this。
synchronized修饰static的方法时,方法中无法使用this,所以它锁的不是this,而是这个类。所以,static synchronized方法也相当于全局锁。
使用synchronized关键字,应尽量缩小代码块的范围,最好能在代码块上加同步,而不是在整个方法上加同步。因为你锁的范围大的话,时间又长,别的线程就不会获得相应的资源。
A线程持有对象的锁,B线程可以以异步方式调用对象中的非synchronized同步的方法。
java多线程(四)的更多相关文章
- java 多线程四
java 多线程一 java 多线程二 java 多线程三 java 多线程四 一个生产者,消费者的例子: import java.util.Stack; /** * Created by root ...
- java多线程(四)-自定义线程池
当我们使用 线程池的时候,可以使用 newCachedThreadPool()或者 newFixedThreadPool(int)等方法,其实我们深入到这些方法里面,就可以看到它们的是实现方式是这样的 ...
- Java多线程(四) 线程池
一个优秀的软件不会随意的创建.销毁线程,因为创建和销毁线程需要耗费大量的CPU时间以及需要和内存做出大量的交互.因此JDK5提出了使用线程池,让程序员把更多的精力放在业务逻辑上面,弱化对线程的开闭管理 ...
- java多线程四种实现模板
假设一个项目拥有三块独立代码块,需要执行,什么时候用多线程? 这些代码块某些时候需要同时运行,彼此独立,那么需要用到多线程操作更快... 这里把模板放在这里,需要用的时候寻找合适的来选用. 总体分为两 ...
- Java多线程(四) —— 线程并发库之Atomic
一.从原子操作开始 从相对简单的Atomic入手(java.util.concurrent是基于Queue的并发包,而Queue,很多情况下使用到了Atomic操作,因此首先从这里开始). 很多情况下 ...
- java多线程(四)之同步机制
1.同步的前提 多个线程 多个线程使用的是同一个锁 2.同步的好处 同步的出现解决了多线程的安全问题 3.同步的弊端 当线程较多时, 因为每个线程都会去判断同步上的锁, 这样是很耗费资源的, 会降低程 ...
- java多线程(四)
一个例子: Account.java 客户实体类 package com.asiainfo.test.thread8; /** * 账户类 * @author luke * */ public cla ...
- JAVA多线程(四) Executor并发框架向RabbitMQ推送消息
github代码地址: https://github.com/showkawa/springBoot_2017/tree/master/spb-demo/spb-brian-query-service ...
- Java多线程——<四>让线程有返回值
一.概述 到目前为止,我们已经能够声明并使一个线程任务运行起来了.但是遇到一个问题:现在定义的任务都没有任何返回值,那么加入我们希望一个任务运行结束后告诉我一个结果,该结果表名任务执行成功或失败,此时 ...
- Java多线程——<八>多线程其他概念
一.概述 到第八节,就把多线程基本的概念都说完了.把前面的所有文章加连接在此: Java多线程——<一>概述.定义任务 Java多线程——<二>将任务交给线程,线程声明及启动 ...
随机推荐
- Post方式调用wcf服务
我们平常在PC端调用WCF服务,只要知道WCF服务的地址,客户端直接添加引用服务就可以使用了,殊不知还有其他方式,其实,我们也可以 通过HTTP POST的方式调用WCF服务,这样就不用添加引用了,在 ...
- oracle 触发器 pragma autonomous_transaction
from:http://blog.csdn.net/ruru7989/article/details/30712987一般情况下在触发器中是不能使用DDL语句的,使用自治事务可以实现 可以在触发器中加 ...
- BZOJ 1089 SCOI2003 严格n元树 动态规划+高精度
题目大意:定义一棵深度为d的严格n元树为根的深度为0,最深的节点深度为d,且每一个非叶节点都有恰好n个子节点的树 给定n和d,求深度为d的严格n元树一共同拥有多少种 此题的递推部分并不难 首先我们设深 ...
- XML高速入门
XML是什么 Extensible Markup Language 自己定义标签: 用来数据传输: 可扩展标记语言,是一种类似超文本标记语言的标记语言. 与HTML的比較: 1.不是用来替代HTML的 ...
- POJ 1837 Balance(01背包变形, 枚举DP)
Q: dp 数组应该怎么设置? A: dp[i][j] 表示前 i 件物品放入天平后形成平衡度为 j 的方案数 题意: 有一个天平, 天平的两侧可以挂上重物, 给定 C 个钩子和G个秤砣. 2 4 - ...
- Ini操作类
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using S ...
- eclipse中debug模式不能启动运行,run运行模式却能启动运行!
这个问题我郁闷了好久!问题原因:因为断点太多了,断点冲突了. 解决办法:只要进如deug界面,选择BreakPoints选项,然后清除所有断点,再重新debug启动.问题解决! 希望能帮到遇到此问题的 ...
- js array.filter实例(数组去重)
语法: 循环对数组中的元素调用callback函数, 如果返回true 保留,如果返回false 过滤掉, 返回新数组,老数组不变 var new_array = source_array.filt ...
- php学习十四:抽象,接口和多态
多态为面向对象编程的精华所在,js等面向过程的语言虽然可以模拟面向对象,但是毕竟模仿的永远比不上真的,所以了解而且会使用面向对象的多态是必不可少的 在了解多态之前,我们必须要了解接口,但是接口又是在抽 ...
- Go基础---->go的基础学习(三)
这里面我们简单的介绍go中面向对象编程的知识. Go的面向对象编程 一.为类型添加方法 package main import "fmt" type Integer int // ...