Java并发编程_synchronized关键字的用法(一)
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关键字的用法(一)的更多相关文章
- Java并发编程_volatile关键字的用法(二)
被volatile修饰的变量能够保证每个线程能够获取该变量的最新值,从而避免出现数据脏读的现象. 根据下面实例理解: package sync; public class VolatileTest e ...
- Java并发编程 Volatile关键字解析
volatile关键字的两层语义 一旦一个共享变量(类的成员变量.类的静态成员变量)被volatile修饰之后,那么就具备了两层语义: 1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了 ...
- Java并发编程1--synchronized关键字用法详解
1.synchronized的作用 首先synchronized可以修饰方法或代码块,可以保证同一时刻只有一个线程可以执行这个方法或代码块,从而达到同步的效果,同时可以保证共享变量的内存可见性 2.s ...
- Java并发编程volatile关键字
volatile理解 Java语言是支持多线程的,为了解决线程并发的问题,在语言内部引入了 同步块 和volatile 关键字机制.volatile具有synchronized关键字的“可见性”,vo ...
- java并发编程 volatile关键字 精准理解
1.volatile的作用 一个线程共享变量(类的成员变量.类的静态成员变量等)被volatile修饰之后,就具有以下作用: 1)并发中的变量可见性(不同线程对该变量进行操作时的可见性),即一个线程修 ...
- Java并发编程:volatile关键字解析
Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在 ...
- (转)Java并发编程:volatile关键字解析
转:http://www.cnblogs.com/dolphin0520/p/3920373.html Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或 ...
- Java并发编程:volatile关键字解析(转载)
转自https://www.cnblogs.com/dolphin0520/p/3920373.html Java并发编程:volatile关键字解析 Java并发编程:volatile关键字解析 ...
- Java并发编程学习:volatile关键字解析
转载:https://www.cnblogs.com/dolphin0520/p/3920373.html 写的非常棒,好东西要分享一下 Java并发编程:volatile关键字解析 volatile ...
随机推荐
- CentOS/redhat使用光盘镜像源
1,首先进行光盘的挂载,注意光盘挂载时不会自动建立目录的, 所以需要自己建立目录. mkdir /mnt/cdrom mount /dev/cdrom /mnt/cdrom #de ...
- HDU 4812 D Tree
HDU 4812 思路: 点分治 先预处理好1e6 + 3以内到逆元 然后用map 映射以分治点为起点的链的值a 成他的下标 u 然后暴力跑出以分治点儿子为起点的链的值b,然后在map里查找inv[b ...
- 最常出现的字符串 Most Common Word
2018-10-26 00:32:05 问题描述: 问题求解: 方法一.Trie 最长出现的字符串,最容易想到的解法就是Trie树了,于是首先使用Trie树进行了实现,代码量有点大,当然了是可以A掉的 ...
- windows10 64bit 下的tensorflow 安装及demo
目前流行的深度学习库有Caffe,Keras,Theano,本文采用谷歌开源的曾用来制作AlphaGo的深度学习系统Tensorflow. 1:安装Tensorflow 最早TensorFlow只支持 ...
- Windows 下 Redis 服务无法启动,错误 1067 进程意外终止解决方案
1.检查端口是否被占用 2.修改 Windows 服务里的 Redis 服务为本地系统服务(修改方式见下文) 方法: 1.看系统日志 桌面计算机/此电脑(Win10名称)右键打开管理,或 Win+R ...
- 通过wifi 连接 adb 到 手机
网上很多文章都需要先用 usb 线连接先做一下设置,然后才能通过下面的方法连接 julian@julian-ThinkPad-T450:~/tools/android_sdk/platform-too ...
- 雷林鹏分享:XML 用途
XML 用途 XML 应用于 Web 开发的许多方面,常用于简化数据的存储和共享. XML 把数据从 HTML 分离 如果您需要在 HTML 文档中显示动态数据,那么每当数据改变时将花费大量的时间来编 ...
- 20171205xlVBA往返航班组合
'ClassPlan Public Org As String Public Des As String Public FlyNo As String Public StartDate As Vari ...
- MVC,MVVM,MVP的区别/ Vue中忽略的知识点!
按照顺序学习: https://scotch.io/courses/build-an-online-shop-with-vue/hello-world Vue Authentication And R ...
- DAG最长路问题 hdu-1224
用DFS+记忆化写了一下,拓扑排序+DP的我还没弄明白.据说Codeforces 721C就是这类题目,因为有费用限制,DFS不太好写,有时间把DP法想明白来. #include <iostre ...