参考博客

Java多线程系列--“基础篇”04之 synchronized关键字

synchronized基本规则

第一条 当线程访问A对象的synchronized方法和同步块的时候,其他线程无法访问A对象的synchronized方法和同步块
第二条 当线程访问A对象的synchronized方法和同步块的时候,其他线程可以访问A对象的非synchronized方法和同步块
第三条 当线程访问A对象的synchronized方法和同步块的时候,其他线程不可以访问A对象其他synchronizedd方法和同步块

第三条基本原则测试



import lombok.extern.slf4j.Slf4j;

@Slf4j
public class SysDemo3 {
public static void main(String[] args) {
final Count count =new Count();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
count.synMethodA();
}
},"t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
count.synMethodB();
}
},"t2");
t1.start();
t2.start();
} }
@Slf4j
class Count {
int countsize =5; public synchronized void synMethodA(){
int count =0;
while(count<countsize){
log.info("synMethodA, Current thread is : {}, count = {}",Thread.currentThread().getName(),count++);
} }
public synchronized void synMethodB(){
int count =0;
while(count<countsize){
log.info("synMethodB, Current thread is : {}, count = {}",Thread.currentThread().getName(),count++);
} }
}

测试结果

2019-07-25 13:40:44,482   [t1] INFO  Count  - synMethodA, Current thread is : t1, count = 0
2019-07-25 13:40:44,482 [t1] INFO Count - synMethodA, Current thread is : t1, count = 1
2019-07-25 13:40:44,482 [t1] INFO Count - synMethodA, Current thread is : t1, count = 2
2019-07-25 13:40:44,482 [t1] INFO Count - synMethodA, Current thread is : t1, count = 3
2019-07-25 13:40:44,482 [t1] INFO Count - synMethodA, Current thread is : t1, count = 4
2019-07-25 13:40:44,482 [t2] INFO Count - synMethodB, Current thread is : t2, count = 0
2019-07-25 13:40:44,482 [t2] INFO Count - synMethodB, Current thread is : t2, count = 1
2019-07-25 13:40:44,482 [t2] INFO Count - synMethodB, Current thread is : t2, count = 2
2019-07-25 13:40:44,482 [t2] INFO Count - synMethodB, Current thread is : t2, count = 3
2019-07-25 13:40:44,482 [t2] INFO Count - synMethodB, Current thread is : t2, count = 4

说明

每个对象都有一把同步锁,同步锁是依赖对象存在的。上面的结果说明当A对象的同步方法或者同步块被调用的时候,这把锁

就在使用者中,其他的使用者调用A对象的同步方法或者同步块的时候,是不会获取到锁的。

实例锁与全局锁

实例锁是锁在对象上

全局锁是锁在类上,static syncronized方法或者同步块

不同的线程调用一个类的不同的static syncronized方法。

不同的线程调用一个类的不同的static syncronized方法:x.classSyn1()与y.classSyn2(),x不释放,y是无法运行静态同步方法的。

测试


import lombok.extern.slf4j.Slf4j; import static java.lang.Thread.sleep;
/*
全局锁的使用,类的static syncronized方法或代码块被线程调用,
其他线程没有拥有全局锁,无法调用其他的同步方法和同步块
*/
@Slf4j
public class SysDemo5 {
static class Count {
static int countsize =5; public synchronized void synMethodA(){
int count =0;
while(count<countsize){
log.info("synMethodA, Current thread is : {}, count = {}",Thread.currentThread().getName(),count++);
try {
sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
} }
public synchronized void synMethodB(){
int count =0; while(count<countsize){
log.info("synMethodB, Current thread is : {}, count = {}",Thread.currentThread().getName(),count++);
try {
sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
} }
public static synchronized void cSynMethodA(){
int count =0;
while(count<countsize){
log.info("class synMethodA, Current thread is : {}, count = {}",Thread.currentThread().getName(),count++);
try {
sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static synchronized void cSynMethodB(){
int count =0;
while(count<countsize){
log.info("class synMethodB, Current thread is : {}, count = {}",Thread.currentThread().getName(),count++);
try {
sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
Count.cSynMethodA();
}
},"t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
Count.cSynMethodB();
}
},"t2");
t1.start();
t2.start();
}
}

测试结果

2019-07-25 17:31:24,358   [t1] INFO  SysDemo5  - class synMethodA, Current thread is : t1, count = 0
2019-07-25 17:31:24,857 [t1] INFO SysDemo5 - class synMethodA, Current thread is : t1, count = 1
2019-07-25 17:31:25,356 [t1] INFO SysDemo5 - class synMethodA, Current thread is : t1, count = 2
2019-07-25 17:31:25,855 [t1] INFO SysDemo5 - class synMethodA, Current thread is : t1, count = 3
2019-07-25 17:31:26,354 [t1] INFO SysDemo5 - class synMethodA, Current thread is : t1, count = 4
2019-07-25 17:31:26,853 [t2] INFO SysDemo5 - class synMethodB, Current thread is : t2, count = 0
2019-07-25 17:31:27,351 [t2] INFO SysDemo5 - class synMethodB, Current thread is : t2, count = 1
2019-07-25 17:31:27,850 [t2] INFO SysDemo5 - class synMethodB, Current thread is : t2, count = 2
2019-07-25 17:31:28,349 [t2] INFO SysDemo5 - class synMethodB, Current thread is : t2, count = 3
2019-07-25 17:31:28,847 [t2] INFO SysDemo5 - class synMethodB, Current thread is : t2, count = 4

x.classSyn1与x.sysn1

对象的同步方法和类的同步方法互不影响

测试

import lombok.extern.slf4j.Slf4j;

import static java.lang.Thread.sleep;

@Slf4j
public class SysDemo4 {
static class Count {
static int countsize =5; public synchronized void synMethodA(){
int count =0;
while(count<countsize){
log.info("synMethodA, Current thread is : {}, count = {}",Thread.currentThread().getName(),count++);
try {
sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
} }
public synchronized void synMethodB(){
int count =0; while(count<countsize){
log.info("synMethodB, Current thread is : {}, count = {}",Thread.currentThread().getName(),count++);
try {
sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
} }
public static synchronized void cSynMethodA(){
int count =0;
while(count<countsize){
log.info("class synMethodA, Current thread is : {}, count = {}",Thread.currentThread().getName(),count++);
try {
sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
final Count count =new Count();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
count.synMethodA();
}
},"t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
Count.cSynMethodA();
}
},"t2");
t1.start();
t2.start();
} }

测试结果

2019-07-25 19:04:53,184   [t2] INFO  SysDemo4  - class synMethodA, Current thread is : t2, count = 0
2019-07-25 19:04:53,199 [t1] INFO SysDemo4 - synMethodA, Current thread is : t1, count = 0
2019-07-25 19:04:53,683 [t2] INFO SysDemo4 - class synMethodA, Current thread is : t2, count = 1
2019-07-25 19:04:53,699 [t1] INFO SysDemo4 - synMethodA, Current thread is : t1, count = 1
2019-07-25 19:04:54,182 [t2] INFO SysDemo4 - class synMethodA, Current thread is : t2, count = 2
2019-07-25 19:04:54,198 [t1] INFO SysDemo4 - synMethodA, Current thread is : t1, count = 2
2019-07-25 19:04:54,682 [t2] INFO SysDemo4 - class synMethodA, Current thread is : t2, count = 3
2019-07-25 19:04:54,697 [t1] INFO SysDemo4 - synMethodA, Current thread is : t1, count = 3
2019-07-25 19:04:55,181 [t2] INFO SysDemo4 - class synMethodA, Current thread is : t2, count = 4
2019-07-25 19:04:55,197 [t1] INFO SysDemo4 - synMethodA, Current thread is : t1, count = 4 Process finished with exit code 0

java并发(二):初探syncronized的更多相关文章

  1. Java并发(二):基础概念

    并发编程的第二部分,先来谈谈发布(Publish)与逸出(Escape); 发布是指:对象能够在当前作用域之外的代码中使用,例如:将对象的引用传递到其他类的方法中,对象的引用保存在其他类可以访问的地方 ...

  2. Java并发编程初探

    package test; import java.io.File; import java.io.FileReader; import java.io.IOException; import jav ...

  3. java并发:初探消费者和生产者模式

    消费者和生产者模式 用继承Thread方式,用wait和notifyAll方法实现. 消费者和生产者模式的特点 1. 什么时候生产:仓库没有满的时候,生产者这可以生产,消费者也可以消费,仓库满的时候停 ...

  4. java并发:初探用户线程和守护线程

    用户线程和守护线程 用户线程 用户线程执行完,jvm退出.守护线程还是可以跑的 /** * A <i>thread</i> is a thread of execution i ...

  5. java并发初探ConcurrentHashMap

    java并发初探ConcurrentHashMap Doug Lea在java并发上创造了不可磨灭的功劳,ConcurrentHashMap体现这位大师的非凡能力. 1.8中ConcurrentHas ...

  6. 【Java并发编程实战】----- AQS(二):获取锁、释放锁

    上篇博客稍微介绍了一下AQS,下面我们来关注下AQS的所获取和锁释放. AQS锁获取 AQS包含如下几个方法: acquire(int arg):以独占模式获取对象,忽略中断. acquireInte ...

  7. Java并发基础框架AbstractQueuedSynchronizer初探(ReentrantLock的实现分析)

    AbstractQueuedSynchronizer是实现Java并发类库的一个基础框架,Java中的各种锁(RenentrantLock, ReentrantReadWriteLock)以及同步工具 ...

  8. Java并发编程二三事

    Java并发编程二三事 转自我的Github 近日重新翻了一下<Java Concurrency in Practice>故以此文记之. 我觉得Java的并发可以从下面三个点去理解: * ...

  9. java 并发多线程 锁的分类概念介绍 多线程下篇(二)

    接下来对锁的概念再次进行深入的介绍 之前反复的提到锁,通常的理解就是,锁---互斥---同步---阻塞 其实这是常用的独占锁(排它锁)的概念,也是一种简单粗暴的解决方案 抗战电影中,经常出现为了阻止日 ...

随机推荐

  1. python中,字符串前的u,b,r字符的含义

    1.字符串前加 u 例:u"我是含有中文字符组成的字符串." 作用: 后面字符串以 Unicode 格式 进行编码,一般用在中文字符串前面,防止因为源码储存格式问题,导致再次使用时 ...

  2. 刷题64. Minimum Path Sum

    一.题目说明 题目64. Minimum Path Sum,给一个m*n矩阵,每个元素的值非负,计算从左上角到右下角的最小路径和.难度是Medium! 二.我的解答 乍一看,这个是计算最短路径的,迪杰 ...

  3. devexpress layoutview

    1.设定数据源 2.设置view 3.设置 templat cardview 4 显示

  4. xshell 快捷键总结

    ##快捷键 linux tab == 命令补全,路径补全.如果tab不到,就代表对于当前用户环境系统找不到这个目录或者路径,有可能有,但是没有放在PATH中 ctrl + a == a:26个字母的第 ...

  5. spring boot jpa 复杂查询 动态查询 连接and和or 模糊查询 分页查询

    最近项目中用到了jpa,刚接触的时候有些激动,以前的到层忽然不用写sql不用去自己实现了,只是取个方法名就实现了,太惊艳了,惊为天人,但是慢慢的就发现不是这么回事了,在动态查询的时候,不知道怎么操作了 ...

  6. Cisco AP-格式化AP

    故障情况:APC11-AP04#sho capwap ip config LWAPP Static IP ConfigurationIP Address         172.17.239.204I ...

  7. c++ 读取、输出txt文件

    下面这段话转自:https://blog.csdn.net/lightlater/article/details/6326338 关于文本文件的文件头 第一 ANSI文件的文件头为空,不需要处理: 第 ...

  8. 【SSM】Log4j 日志配置

    1.log4j.properties ### 配置根 ### # log4j.rootLogger = debug,console ,fileAppender,dailyRollingFile,ROL ...

  9. iOS APP语言国际化之应用内切换语言环境

    最近接了一个项目,需求是要做一款应用的英文版本,客户并不清楚,以为要另做一个APP.沟通后告诉他们在之前应用基础上加个国际化功能就好,把之前的语言国际化重新梳理记录一下. 一般设置更改本地语言环境后, ...

  10. 洛谷 T8088 RQY的舞会

    嗯... 题目链接:https://www.luogu.org/problem/T8088 这道题很好想,我想的是维护两个小根堆(当然可以用数组模拟) 然后从堆顶开始,如果两个元素的差小于1,则cnt ...