synchronized基础
synchronized 例子
例1,没有同步的时候运行同一个对象的同一个方法的结果:
public class TestSyn {
public void showMsg() {
try {
for (int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
Thread.sleep(200);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
TestSyn testSyn = new TestSyn();
ExecutorService executorService = Executors.newFixedThreadPool(10);
Runnable runnable = new Runnable() {
@Override
public void run() {
testSyn.showMsg();
}
};
Runnable runnable2 = new Runnable() {
@Override
public void run() {
testSyn.showMsg();
}
};
executorService.execute(runnable);
executorService.execute(runnable2);
executorService.shutdown();
}
}
结果:

可以看到,是同时在执行一个方法里面的内容,没有进行同步
例2,当我们其它不变,只是在方法上加synchronized后:
public class TestSyn {
public synchronized void showMsg() {
try {
for (int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
Thread.sleep(200);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
结果:

可以看到是一个方法执行完后再执行下一次,已经进行了同步
例3,我们在添加另外一个synchronized后观察运行结果:
public class TestSyn {
public synchronized void showMsg() {
try {
for (int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
Thread.sleep(200);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void showMsg2() {
try {
for (int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
Thread.sleep(200);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
TestSyn testSyn = new TestSyn();
ExecutorService executorService = Executors.newFixedThreadPool(10);
Runnable runnable = new Runnable() {
@Override
public void run() {
testSyn.showMsg();
}
};
Runnable runnable2 = new Runnable() {
@Override
public void run() {
testSyn.showMsg2();
}
};
executorService.execute(runnable);
executorService.execute(runnable2);
executorService.shutdown();
}
}

发不同的两个方法依然进行了同步。
我们重新新建一个对象,执行相同的同步函数观察结果:
public class TestSyn {
public synchronized void showMsg() {
try {
for (int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
Thread.sleep(200);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
TestSyn testSyn = new TestSyn();
TestSyn testSyn2 = new TestSyn();
ExecutorService executorService = Executors.newFixedThreadPool(10);
Runnable runnable = new Runnable() {
@Override
public void run() {
testSyn.showMsg();
}
};
Runnable runnable2 = new Runnable() {
@Override
public void run() {
testSyn2.showMsg();
}
};
executorService.execute(runnable);
executorService.execute(runnable2);
executorService.shutdown();
}
}

发现不同对象的同一个方法没有进行同步
例4,我们换成一个static方法添加synchronized后:
public class TestSyn {
public synchronized void showMsg() {
try {
for (int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
Thread.sleep(200);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized static void showMsg2() {
try {
for (int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
Thread.sleep(200);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
TestSyn testSyn = new TestSyn();
ExecutorService executorService = Executors.newFixedThreadPool(10);
Runnable runnable = new Runnable() {
@Override
public void run() {
testSyn.showMsg();
}
};
Runnable runnable2 = new Runnable() {
@Override
public void run() {
TestSyn.showMsg2();
}
};
executorService.execute(runnable);
executorService.execute(runnable2);
executorService.shutdown();
}
}

发现又没有进行同步了。
结论:
1.某个对象实例内,synchronized aMethod(){}关键字可以防止多个线程访问对象的synchronized方法(如果一个对象有多个synchronized方法,只要一个线程访问了其中的一个synchronized方法,其它线程不能同时访问这个对象中任何一个synchronized方法)。这时,不同的对象实例的synchronized方法是不相干扰的。也就是说,其它线程照样可以同时访问相同类的另一个对象实例中的synchronized方法
2.是某个类的范围,synchronized static aStaticMethod{}防止多个线程同时访问这个类中的synchronized static 方法。它可以对类的所有对象实例起作用
3.如果同一对象两个synchronized方法一个是非static方法和static方法,是不相干扰的
4.synchronized关键字是不能继承的,也就是说,基类的方法synchronized f(){} 在继承类中并不自动是synchronized f(){},而是变成了f(){}。继承类需要你显式的指定它的某个方法为synchronized方法
synchronized基础的更多相关文章
- Synchronized用法原理和锁优化升级过程(面试)
简介 多线程一直是面试中的重点和难点,无论你现在处于啥级别段位,对synchronized关键字的学习避免不了,这是我的心得体会.下面咱们以面试的思维来对synchronized做一个系统的描述,如果 ...
- 面试突击42:synchronized和ReentrantLock有什么区别?
在 Java 中,常用的锁有两种:synchronized(内置锁)和 ReentrantLock(可重入锁),二者的功效都是相同得,但又有很多不同点,所以我们今天就来聊聊. 区别1:用法不同 syn ...
- 并发编程(三):从AQS到CountDownLatch与ReentrantLock
一.目录 1.AQS简要分析 2.谈CountDownLatch 3.谈ReentrantLock 4.谈消费者与生产者模式(notfiyAll/wait.si ...
- Java:并发笔记-03
Java:并发笔记-03 说明:这是看了 bilibili 上 黑马程序员 的课程 java并发编程 后做的笔记 3. 共享模型之管程-2 本章内容-2 Monitor wait/notify 3.6 ...
- Java多线程系列--“基础篇”04之 synchronized关键字
概要 本章,会对synchronized关键字进行介绍.涉及到的内容包括:1. synchronized原理2. synchronized基本规则3. synchronized方法 和 synchro ...
- Java基础-多线程-③线程同步之synchronized
使用线程同步解决多线程安全问题 上一篇 Java基础-多线程-②多线程的安全问题 中我们说到多线程可能引发的安全问题,原因在于多个线程共享了数据,且一个线程在操作(多为写操作)数据的过程中,另一个线程 ...
- Java基础-synchronized关键字的用法(转载)
synchronized--同步 顾名思义是用于同步互斥的作用的. 这里精简的记一下它的使用方法以及意义: 当synchronized修饰 this或者非静态方法或者是一个实例的时候,所同步的锁是加在 ...
- Java多线程系列 基础篇06 synchronized(同步锁)
转载 http://www.cnblogs.com/paddix/ 作者:liuxiaopeng http://www.infoq.com/cn/articles/java-se-16-synchro ...
- 【java基础 14】锁的粒度:ThreadLocal、volatile、Atomic和Synchronized
导读:题目中提到的几个关键字,分别是解决并发问题中,加锁所使用到的几个关键字,每个关键字代表的锁的粒度 不同,本篇博客,主要是从概念定义上,区分这几个关键字的应用场景.(PS:睡梦中,依稀记得有回面试 ...
随机推荐
- 纯C:AES256
尼玛的WordPress把格式全搞乱了 aes256.h #ifndef _AES256_H_ #define _AES256_H_ #include <stdio.h> #include ...
- js 自定义滚动条
http://visugar.com/2017/08/18/20170818CustomScroll/ chrome浏览器 https://www.cnblogs.com/yclblog/p/6 ...
- strchr与sscanf
strchr(s,',')返回字符串s中从左往右第一个字符's'的指针: sscanf(输入的字符或字符串,“%格式符”,存储值):
- review
一.123 第二部分:面向对象 . 谈谈你对面向对象的认识. . 约束 Java: - 接口,约子类中必须包含某个方法(约束). Interface IMessage: def func1(self) ...
- 一道dp[不太好写]
http://acm.csu.edu.cn:20080/csuoj/problemset/problem?pid=2281 Description An arithmetic progression ...
- 解决ERROR - unregister mbean error javax.management.InstanceNotFoundException: com.alibaba.druid:type=
https://blog.csdn.net/chengsi101/article/details/72627062 https://www.cnblogs.com/gradven/p/6323195. ...
- nginx常用参数设置
1)隐藏nginx header 版本号 使用curl -I http://www.10.0.3.46 会发现server那里显示版本号 在nginx.conf的http里添加参数server_tok ...
- mysql配置my.cnf文件,以及参数优化提升性能
系统centos7 mariadb通过yum安装 mysql配置文件位于/etc/my.cnf 常用参数: 1)max_connections设置最大连接(用户)数,其默认值为100,设置太小会出现t ...
- MySQL Binlog和Relaylog生成和清理
=====================================================================================binlog文件生成:在每条二 ...
- day 27 网络通信协议 tup udp 下的socket
1.osi七层模型 通信流程 socket(抽象层): 结合上图来看,socket在哪一层呢,我们继续看下图 socket在内的五层通讯流程: 2.TCP/UDP的区别: TCP是以数据流的形式传输, ...