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:睡梦中,依稀记得有回面试 ...
随机推荐
- 爬取贴吧中的html,并保存到相对应的文件夹中
功能:输入要爬取的贴吧名称,起始页和终止页即可. # -*- coding: utf-8 -*- import urllib.request import urllib.parse import os ...
- [LeetCode&Python] Problem 258. Add Digits
Given a non-negative integer num, repeatedly add all its digits until the result has only one digit. ...
- 使用libcurl作为Http client
产品通过HTTP协议为外部提供接口服务,常规情况是客户通过HTTP协议请求服务,服务结束后通过HTTP协议将服务记录POST到请求方. 用原生C实现了一个简单的HTTP Client,只有简单的功能: ...
- 阿里druid数据库连接池缓存方案
阿里缓存机制:若在进某一页面的时候执行了select语句,会将该select语句查询出来的数据存入缓存,若执行了修改语句则清空该缓存,若没有执行修改语句则再次进入此页面的时候会直接从缓存中加载上次se ...
- HTTP/2及HTTP/3特性
HTTP/2及HTTP/3特性 摘要: 学习 HTTP/2 与 HTTP/3. 前言 HTTP/2 相比于 HTTP/1,可以说是大幅度提高了网页的性能,只需要升级到该协议就可以减少很多之前需要做的性 ...
- django额外参数的传递和url命名
django额外参数的传递 path方法:path(route, view, kwargs=None, name=None) path方法可以传递入一个额外参数的字典参数(kwarg),字典里的值就会 ...
- (13)自定意义标签和过滤器 (templatetags)
过滤器分内置和自定意义 PS:过滤器可以用在for循环和if判断后,但是标签不能使用在for循环和if判断后 内置过滤器: add(在模板中实现加减法) default(就是当传入的变量是False的 ...
- (20)jQuery的文档操作(创建,添加、设置样式和删除等)
<!DOCTYPE html><html><head> <meta charset="UTF-8"> <title>jq ...
- 在使用 interface 声明一个接口时,只可以使用那个修饰符修饰该接口?
这是一个看似简单其实挺有深意的题目,答案应该大多数人都知道是什么,不过原理和原因相比很少有人仔细研究过.对于本题,我有三点说明,希望看到这个评论的人能从这三点中看到你以前没注意到的东西: ①接口的声 ...
- LG2742 【模板】二维凸包 / [USACO5.1]圈奶牛Fencing the Cows
题意 题目描述 农夫约翰想要建造一个围栏用来围住他的奶牛,可是他资金匮乏.他建造的围栏必须包括他的奶牛喜欢吃草的所有地点.对于给出的这些地点的坐标,计算最短的能够围住这些点的围栏的长度. 输入输出格式 ...