synchronized:意思是 同步,也就是 共享资源

Synchronized修饰方法:对象锁

Static Synchronized修饰方法:类锁

下面代码手动敲一遍,就会理解

 一、Synchronized修饰方法

1、一个对象,启动多个线程,竞争一把对象锁

package sync;
/*
* 一个对象,启动多个线程,竞争一把对象锁
*/
public class MyThread extends Thread{ private int count = 5; public synchronized void run() {
count--;
System.out.println(this.currentThread().getName() + " count = " + count);
} public static void main(String[] args) {
//新建一个对象
MyThread myThread = new MyThread();
//启动多个线程
Thread t1 = new Thread(myThread,"t1");
Thread t2 = new Thread(myThread,"t2");
Thread t3 = new Thread(myThread,"t3");
Thread t4 = new Thread(myThread,"t4");
Thread t5 = new Thread(myThread,"t5");
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
}
}

输出结果:

t1 count = 4
t4 count = 3
t5 count = 2
t3 count = 1
t2 count = 0

这五个线程,哪个先执行,哪个后执行,要看CPU调度

2、多个对象,启动多个线程,竞争多把对象锁

package sync;

public class MultiThread {

	private int num = 0;

	public synchronized void printNum(String tag) {
try {
if(tag.equals("a")) {
num = 100;
System.out.println("tag a , set num over!");
Thread.sleep(1000);
System.out.println("tag " + tag + ", num = " + num);
}else {
num = 200;
System.out.println("tag b , set num over!");
Thread.sleep(1000);
System.out.println("tag " + tag + ", num = " + num);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
} public static void main(String[] args) {
//新建两个对象m1 、m2
MultiThread m1 = new MultiThread();
MultiThread m2 = new MultiThread(); //新建第一个线程,调用m1对象的printNum()方法
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
m1.printNum("a");
} });
//新建第二个线程,调用m2对象的printNum()方法
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
m2.printNum("b");
}
});
//同时启动两个线程
t1.start();
t2.start(); //是先执行完线程t1,再执行线程t2吗?
}
}

输出结果:

tag b , set num over!
tag a , set num over!
tag b, num = 200
tag a, num = 100

  

可以看到,线程t1和线程t2是同时执行,两个线程互不影响,独立执行,因此输出结果自然不分先后.

第一个对象m1访问后,锁住m1这个对象;然后,第二个对象m2继续访问,不会被m1锁影响到。

结论:

(1)synchronized是对象锁,多个对象多个锁,锁的是对象。

(2)而不是把一个方法或者一个类当作锁(一个Class类可以new多个对象嘛)

二、Static Synchronized修饰方法

在静态方法上加上synchronized关键字,表示锁定class类,类一级别的锁(独占class类)

无论new多少个对象去访问该静态synchronized方法,都要排队一个个访问,竞争同一把锁(class这个锁)

package sync;

public class MultiThread {

	private static int num = 0;

	public static synchronized void printNum(String tag) {
try {
if(tag.equals("a")) {
num = 100;
System.out.println("tag a , set num over!");
Thread.sleep(1000);
System.out.println("tag " + tag + ", num = " + num);
}else {
num = 200;
System.out.println("tag b , set num over!");
Thread.sleep(1000);
System.out.println("tag " + tag + ", num = " + num);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
} public static void main(String[] args) {
//新建两个对象m1 、m2
MultiThread m1 = new MultiThread();
MultiThread m2 = new MultiThread(); //新建第一个线程,调用m1对象的printNum()方法
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
m1.printNum("a");
} });
//新建第二个线程,调用m2对象的printNum()方法
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
m2.printNum("b");
}
});
//同时启动两个线程
t1.start();
t2.start(); //是先执行完线程t1,再执行线程t2吗?
}
}

  

输出结果:

tag b , set num over!
tag b, num = 200
tag a , set num over!
tag a, num = 100

  

可以看到:

先执行完一个线程b,再执行下一个线程a

结论:

(1)static synchronized是类锁,锁住这个类

Java并发编程_synchronized关键字的用法(一)的更多相关文章

  1. Java并发编程_volatile关键字的用法(二)

    被volatile修饰的变量能够保证每个线程能够获取该变量的最新值,从而避免出现数据脏读的现象. 根据下面实例理解: package sync; public class VolatileTest e ...

  2. Java并发编程 Volatile关键字解析

    volatile关键字的两层语义 一旦一个共享变量(类的成员变量.类的静态成员变量)被volatile修饰之后,那么就具备了两层语义: 1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了 ...

  3. Java并发编程1--synchronized关键字用法详解

    1.synchronized的作用 首先synchronized可以修饰方法或代码块,可以保证同一时刻只有一个线程可以执行这个方法或代码块,从而达到同步的效果,同时可以保证共享变量的内存可见性 2.s ...

  4. Java并发编程volatile关键字

    volatile理解 Java语言是支持多线程的,为了解决线程并发的问题,在语言内部引入了 同步块 和volatile 关键字机制.volatile具有synchronized关键字的“可见性”,vo ...

  5. java并发编程 volatile关键字 精准理解

    1.volatile的作用 一个线程共享变量(类的成员变量.类的静态成员变量等)被volatile修饰之后,就具有以下作用: 1)并发中的变量可见性(不同线程对该变量进行操作时的可见性),即一个线程修 ...

  6. Java并发编程:volatile关键字解析

    Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在 ...

  7. (转)Java并发编程:volatile关键字解析

    转:http://www.cnblogs.com/dolphin0520/p/3920373.html Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或 ...

  8. Java并发编程:volatile关键字解析(转载)

    转自https://www.cnblogs.com/dolphin0520/p/3920373.html Java并发编程:volatile关键字解析   Java并发编程:volatile关键字解析 ...

  9. Java并发编程学习:volatile关键字解析

    转载:https://www.cnblogs.com/dolphin0520/p/3920373.html 写的非常棒,好东西要分享一下 Java并发编程:volatile关键字解析 volatile ...

随机推荐

  1. MYSQL的常用函数(字符串函数)

    ASCII(char)返回字符的ASCII码值 BIT_LENGTH(str)返回字符串的比特长度 CONCAT(s1,s2...,sn)将s1,s2...,sn连接成字符串 CONCAT_WS(se ...

  2. 第 8 章 容器网络 - 052 - overlay 如何实现跨主机通信?

    overlay 如何实现跨主机通信? 在 host2 中运行容器 bbox2: docker run -itd --name bbox2 --network ov_net1 busybox bbox2 ...

  3. Google Bazel简介

    最近跑一个代码,需要用到Bazel. Bazel

  4. 单细胞文章分享:Molecular Diversity of Midbrain Development in Mouse, Human, and Stem Cells

    Molecular Diversity of Midbrain Development in Mouse, Human, and Stem Cells 本文作者的官网:Ventral midbrain ...

  5. LeetCode--844--比较含退格的字符串(java)

    给定 S 和 T 两个字符串,当它们分别被输入到空白的文本编辑器后,判断二者是否相等,并返回结果. # 代表退格字符. 示例 1: 输入:S = "ab#c", T = " ...

  6. eclipse 快捷键Open Implementation 直接退出

    遇到eclipse 快捷键Open  Implementation 非正常退出.直接关闭的现象. 网查了一下   碰到一篇博客说  和google 输入法有关  卸载了google 输入法就好了 半信 ...

  7. hdu-2639 Bone Collector II 背包第K优

    http://acm.hdu.edu.cn/showproblem.php?pid=2639 在背包的基础上维护一个size<=K的最大值集合,为什么维护K个就好了呢,因为如果当前状态有多余K个 ...

  8. 在项目中使用react

    1. 运行 ’cnpm i react react-dom -S' 安装包 react:专门用于创建组件和虚拟DOM,同时组件的生命周期都在这个包中 react-dom:专门进行DOM操作,主要应用场 ...

  9. genymotio安装apk包提示 ...abi ...cpu

    下载 Genymotion-ARM-Translation_v1.1 (1).zip 地址:http://qc1.androidfilehost.com/dl/Q-YDDKt4QaFNvKh62ppO ...

  10. Sonya and Matrix CodeForces - 1004D (数学,构造)

    http://codeforces.com/contest/1004/problem/D 题意:网格图给定到中心点的曼哈顿距离数组, 求该图n,m及中心点位置 首先可以观察到距离最大值mx一定在某个角 ...