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基础的更多相关文章

  1. Synchronized用法原理和锁优化升级过程(面试)

    简介 多线程一直是面试中的重点和难点,无论你现在处于啥级别段位,对synchronized关键字的学习避免不了,这是我的心得体会.下面咱们以面试的思维来对synchronized做一个系统的描述,如果 ...

  2. 面试突击42:synchronized和ReentrantLock有什么区别?

    在 Java 中,常用的锁有两种:synchronized(内置锁)和 ReentrantLock(可重入锁),二者的功效都是相同得,但又有很多不同点,所以我们今天就来聊聊. 区别1:用法不同 syn ...

  3. 并发编程(三):从AQS到CountDownLatch与ReentrantLock

    一.目录      1.AQS简要分析      2.谈CountDownLatch      3.谈ReentrantLock      4.谈消费者与生产者模式(notfiyAll/wait.si ...

  4. Java:并发笔记-03

    Java:并发笔记-03 说明:这是看了 bilibili 上 黑马程序员 的课程 java并发编程 后做的笔记 3. 共享模型之管程-2 本章内容-2 Monitor wait/notify 3.6 ...

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

    概要 本章,会对synchronized关键字进行介绍.涉及到的内容包括:1. synchronized原理2. synchronized基本规则3. synchronized方法 和 synchro ...

  6. Java基础-多线程-③线程同步之synchronized

    使用线程同步解决多线程安全问题 上一篇 Java基础-多线程-②多线程的安全问题 中我们说到多线程可能引发的安全问题,原因在于多个线程共享了数据,且一个线程在操作(多为写操作)数据的过程中,另一个线程 ...

  7. Java基础-synchronized关键字的用法(转载)

    synchronized--同步 顾名思义是用于同步互斥的作用的. 这里精简的记一下它的使用方法以及意义: 当synchronized修饰 this或者非静态方法或者是一个实例的时候,所同步的锁是加在 ...

  8. Java多线程系列 基础篇06 synchronized(同步锁)

    转载 http://www.cnblogs.com/paddix/ 作者:liuxiaopeng http://www.infoq.com/cn/articles/java-se-16-synchro ...

  9. 【java基础 14】锁的粒度:ThreadLocal、volatile、Atomic和Synchronized

    导读:题目中提到的几个关键字,分别是解决并发问题中,加锁所使用到的几个关键字,每个关键字代表的锁的粒度 不同,本篇博客,主要是从概念定义上,区分这几个关键字的应用场景.(PS:睡梦中,依稀记得有回面试 ...

随机推荐

  1. Linux 修改最大连接数脚本

    #!/bin/bashfileMax=$(grep "fs.file-max" /etc/sysctl.conf | wc -l)if [ $fileMax -eq 1 ];the ...

  2. urllib模块通过post请求获取数据

    功能: 输入你要查找的单词,会返回相对应的结果 import urllib.request import urllib.parse import json class youdaoSpider: de ...

  3. 利用Git hub创建博客

    1.准备工作 到Git官网 下载Git,并且配置环境变量 2.注册Git Hub账号 到Git Hub官网注册相关账号,比如本文的账号为13627225740L,并至New repository创建仓 ...

  4. 02 http,servlet,servletconfig,HttpServletRequest ,HttpServletResponse

    Http协议 协议:双方在交互.通讯的时候, 遵守的一种规范.规则.http协议:针对网络上的客户端 与 服务器端在执行http请求的时候,遵守的一种规范. 其实就是规定了客户端在访问服务器端的时候, ...

  5. 《DSP using MATLAB》Problem 5.30

    代码: %% ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ %% Output In ...

  6. org.apache.commons.lang3.StringUtils中的StringUtils常用方法

    https://my.oschina.net/funmo/blog/615202?p=1 public static void TestStr(){ //null 和 ""操作~~ ...

  7. MySQL--线程池(Thread Pool)

    ================================================================= 线程池技术 在MySQL社区版中,MySQL使用one-thread ...

  8. day5 python学习

    本日主要讲了列表的一些操作 1.列表的增 ret=['wang','taibai','alxe','ritian'] ret.append("wusir") print(ret) ...

  9. nginx http2 push 试用

    nginx 已经很早就支持http2,今天证书过期,重新申请了一个,同时测试下http2 的push 功能 环境准备 证书 这个结合自己的实际去申请,我使用免费的letsencrypt,支持泛域名证书 ...

  10. 深入详解美团点评CAT跨语言服务监控(一) CAT简介与部署

    前言: CAT是一个实时和接近全量的监控系统,它侧重于对Java应用的监控,除了与点评RPC组件融合的很好之外,他将会能与Spring.MyBatis.Dubbo 等框架以及Log4j 等结合,支持P ...