参考博客

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. Codeforces Round #576 (Div. 2) 题解

    比赛链接:https://codeforc.es/contest/1199 A. City Day 题意:给出一个数列,和俩个整数\(x,y\),要求找到序号最靠前的数字\(d\),使得\(d\)满足 ...

  2. 「CF815C」Karen and Supermarket

    传送门 Luogu 解题思路 树形背包. 设 \(f[i][j][0/1]\) 表示在以 \(i\) 为根的子树中选 \(j\) 件商品的最少花费. 边界条件: \(f[i][j][0] = \min ...

  3. 登录oracle ORA-12541: TNS:no listener报错

    初次安装Oracle是通过VMware在虚拟机上安装的,安装Oracle过程,解锁了两个用户,分别是Scott和HR,也设置了密码,安装完成后输入sqlplus scott/admin123(scot ...

  4. 《Airbnb 早期BP》---创业学习--训练营直播第3课--HHR

    1,Airbnb:300亿美金. 一,BP 价值: 1,优秀的BP原则: (1)UCD原则:user centered design,用户为中心的设计.站在投资人视角,回答最关心的问题. (2)清晰原 ...

  5. CodeForces-220B Little Elephant and Array

    小象喜欢玩数组.他有一个数组a,由n个正整数组成,从1到n进行索引.让我们用索引i表示数字ai. 此外,小象对数组还有m个查询,每个查询的特征是一对整数lj和rj(1 ≤ lj ≤ rj ≤ n).对 ...

  6. eclipse修改工作空间编码格式

    一.修改workspace默认编码 eclipse打开window -> 打开preferences 二.修改jsp默认编码 eclipse打开window -> 打开preference ...

  7. window照片查看器无法查看照片的问题

    查看其他照片都可以,只有特殊的两张无法查看.百度|| 修改了环境变量中的tmp变量,路径改为e:\tmp(注:要选择磁盘空间足够的磁盘). 刷新过后,重新打开同一张图片,如下: 用系统自带画图软件尝试 ...

  8. Hive的安装与基础指令

    一.Hive安装 Hive的安装相对比较简单,Hive是基于Hadoop来使用的,所以搭建Hadoop伪分布式或完全分布式即可,Hive安装过程如下: ①安装并启动Hadoop 在博主的其他博客中有安 ...

  9. 2019年 我的phper之路,时光没了,头发还在

    前言 曾经我认为最快的是麦迪的第一步,后来我觉得 7 酱逃跑速度更快,现在我懂了,原来我们都在跟时间赛跑. 年底了,给自己一个 "交代" 吧 2019 的我 2019 年写了 很多 ...

  10. mapreduce课上测试

    今天上课的时候进行了一个mapreduce的实验,但是由于课下对于mapreduce还有hive的理解不够透彻,因此导致了课上没能完成这次实验. 关于本次课堂上的实验的内容大致为: 1.对一个70k的 ...