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. 函数式编程(Function Program Language)

    WHAT: 简单说,"函数式编程"是一种"编程范式",也就是如何编写程序的方法论. 它属于"结构化编程"的一种,主要思想是把运算过程尽量写成 ...

  2. poj 2387——单源最短路权值大于0

    因为之前做过这个题.所以这次知道这道题有重边.这次dijkstra的写法加入了优先队列的优化 优先队列 结构体从小到大顺序的两种重载运算符的方式 bool operator <(const Ti ...

  3. A Spy in the Metro(UVA 1025 ACM/ICPC World Finals2003)

    ---恢复内容开始--- 题意:有n(2<=n<=50)个车站,从左到右编号为1~n,有M1辆列车从第1站向右开,还有M2辆列车从第N站向左开.在时刻0,间谍从第1站出发,目的是在时刻T( ...

  4. rest-framework之分页器

    rest-framework之分页器 本文目录 一 简单分页(查看第n页,每页显示n条) 二 偏移分页(在第n个位置,向后查看n条数据) 三 CursorPagination(加密分页,只能看上一页和 ...

  5. LG1861 星之器

    题意 题目背景 Magic Land 上的时间又过了若干世纪„„ 现在, 人们谈论着一个传说:从前,他们的祖先来到了一个位于东方的岛屿, 那里简直就是另外一个世界.善于分析与构造的 Magic Lan ...

  6. day3 zookeeper

    PS:在生产的场景中,一般有两个需求:1.提供设备的注册 2.对所注册的接口进行监听.zookeeper就是提供这样的功能,它本身就是一个集群,如果存在半数以上的节点活着就能提供服务,本身就具备很高的 ...

  7. 深入浅出理解 COOKIE MAPPING

    转载自:http://www.myttnn.com/digital-marketing/cookie-mapping-introduction/ 在RTB(实时竞价广告,Real-Time-Biddi ...

  8. 非系统服务如何随系统启动时自动启动(rc.local加了可执行权限,仍然没有生效)

    我们知道,例如我们直接yum 安装的httpd mysqld之类的服务可以直接systemctl enable mysql使服务自动启动,但是,我们应该关心的是但是的那部分 例如nginx,我的话,我 ...

  9. linux kernel笔记

    文章目录 关于linux内核中的__attribute__关键字 Linux kernel启动参数 gdt / ldt PCB 关于linux内核中的__attribute__关键字 part I: ...

  10. JDBC封装

    在模拟servlet调用dao中,我们发现在dao的实现类中有许多重复代码,我们可以将其封装起来. 步骤: 一. 创建一个类 DBUtil 1加载驱动和建立链接的代码 完全一样 加载驱动写到静态代码快 ...