多线程中的synchronized小结
1.synchronized是Java中的关键字,是一种同步锁。它修饰的对象有以下几种:
1. 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象;
2. 修饰一个方法,被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象;
3. 修改一个静态的方法,其作用的范围是整个静态方法,作用的对象是这个类的所有对象;
4. 修改一个类,其作用的范围是synchronized后面括号括起来的部分,作用主的对象是这个类的所有对象。
2.synchronized的缺陷
synchronized是java中的一个关键字,也就是说是Java语言内置的特性。
如果一个代码块被synchronized修饰了,当一个线程获取了对应的锁,并执行该代码块时,其他线程便只能一直等待,等待获取锁的线程释放锁,而这里获取锁的线程释放锁只会有两种情况:
1)获取锁的线程执行完了该代码块,然后线程释放对锁的占有;
2)线程执行发生异常,此时JVM会让线程自动释放锁。
简单的东西没必要总结,我们来看其中的几个关键点,值得体会,用一个例子说话:
1 public class Demo4 {
public static void main(String[] args) {
final Output output = new Output();
new Thread(new Runnable() {
@Override
public void run() {
while(true){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
output.Output1("chenchi");
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while(true){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
output.Output1("sujunjun");
}
}
}).start();
}
static class Output {
public void Output1(String name) {
synchronized (this) {
for (int i = 0; i < name.length(); i++) {
System.out.print(name.charAt(i));
}
System.out.println();
}
}
public synchronized void Output2(String name) {
for (int i = 0; i < name.length(); i++) {
System.out.print(name.charAt(i));
}
System.out.println();
}
public synchronized static void Output3(String name) {
for (int i = 0; i < name.length(); i++) {
System.out.print(name.charAt(i));
}
System.out.println();
}
}
}
这个例子很简单,就是同时开启两个线程,声明一个Output内部类的对象,同时访问Output内部类的Output()方法。
1.
output.Output1("chenchi");
output.Output1("sujunjun");
很明显,打印中不会出现数据错误。synchronized ()只要保证括号里面是同一对象就不会产生错误。里面传的是this,由于两者对象都是output,所以加锁成功。
想一下,这样会成功吗?(可以)
String string = "";
public void Output1(String name) {
synchronized (string) {
for (int i = 0; i < name.length(); i++) {
System.out.print(name.charAt(i));
}
System.out.println();
}
}
这样呢?(可以)
public void Output1(String name) {
synchronized ("") {
for (int i = 0; i < name.length(); i++) {
System.out.print(name.charAt(i));
}
System.out.println();
}
}
这样呢?(不可以)
public void Output1(String name) {
synchronized (name) {
for (int i = 0; i < name.length(); i++) {
System.out.print(name.charAt(i));
}
System.out.println();
}
}
2.
output.Output1("chenchi");
output.Output2("sujunjun");
很明显,打印中不会出现错误,因为synchronized修饰方法就是相当于给方法加锁的是当前对象。
3.
output.Output1("chenchi");
output.Output3("sujunjun");
很明显,打印会出错。为什么呢?还是因为加锁对象不是同一个了。synchronized修饰静态方法后,上锁对象为当前类对象了。
什么是当前类对象呢?就是Class类型实例,JVM在加载任何一个类时,都会创建一个Class类型的实例描述该类,并且每个类有且只有一个Class的实例描述它。
如何同步?
public void Output1(String name) {
synchronized (Output.class) {
for (int i = 0; i < name.length(); i++) {
System.out.print(name.charAt(i));
}
System.out.println();
}
}
这里改了一下Output1方法,Output.class为上锁对象,就保证了同一对象。
多线程中的synchronized小结的更多相关文章
- 多线程中的synchronized
synchronized是Java中的关键字,是一种同步锁.它修饰的对象有以下几种: 1. 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码 ...
- 多线程中的Lock小结
出处:http://www.cnblogs.com/DarrenChan/p/6528578.html#undefined 1.lock和synchronized的区别 1)Lock不是Java语言内 ...
- java多线程中 volatile与synchronized的区别-阿里面试
volatile 与 synchronized 的比较(阿里面试官问的问题) ①volatile轻量级,只能修饰变量.synchronized重量级,还可修饰方法 ②volatile只能保证数据的可见 ...
- [多线程] 线程中的synchronized关键字锁
为什么要用锁? 在多线程中,难免会出现在多个线程中对同一个对象的实例变量或者全局静态变量进行并发访问的情况,如果不做正确的同步处理,那么产生的后果就是"脏读",也就是取到的数据其实 ...
- java中多线程详解-synchronized
一.介绍 当多个线程涉及到共享数据的时候,就会设计到线程安全的问题.非线程安全其实会在多个线程对同一个对象中的实例变量进行并发访问时发生,产生的后果就是“脏读”.发生脏读,就是取到的数据已经被其他的线 ...
- c#多线程中Lock()关键字的用法小结
本篇文章主要是对c#多线程中Lock()关键字的用法进行了详细的总结介绍,需要的朋友可以过来参考下,希望对大家有所帮助 本文介绍C# lock关键字,C#提供了一个关键字lock,它可以把一段 ...
- 深入理解java中的synchronized关键字
synchronized 关键字,代表这个方法加锁,相当于不管哪一个线程A每次运行到这个方法时,都要检查有没有其它正在用这个方法的线程B(或者C D等),有的话要等正在使用这个方法的线程B(或者C D ...
- BlockingQueue阻塞队列(解决多线程中数据安全问题 可用于抢票,秒杀)
案例:一个线程类中 private static BlockingQueue<Map<String, String>> dataQueue = new LinkedBlocki ...
- java中的synchronized同步代码块和同步方法的区别
下面这两段代码有什么区别? //下列两个方法有什么区别 public synchronized void method1(){} public void method2(){ synchronized ...
随机推荐
- leetcode48:矩阵旋转
题目链接 输入一个N×N的方阵,要求不开辟新空间,实现矩阵旋转. 将点(x,y)绕原点顺时针旋转90度,变为(y,-x).原来的(-y,x)变为(x,y) class Solution(object) ...
- DBA_实践指南系列8_Oracle Erp R12数据维护模式Adadmin(案例)
2013-12-08 Created By BaoXinjian
- python标准库介绍——24 traceback 模块详解
==traceback 模块== [Example 2-18 #eg-2-18] 展示了 ``traceback`` 模块允许你在程序里打印异常的跟踪返回 (Traceback)信息, 类似未捕获异常 ...
- mysql工作中常见问题
1.Error Code: 1044 - Access denied for user 'root'@'localhost' to database 'information_schema'Query ...
- 在Nodejs中贯彻单元测试
在团队合作中,你写好了一个函数,供队友使用,跑去跟你的队友说,你传个A值进去,他就会返回B结果了.过了一会,你队友跑过来说,我传个A值却返回C结果,怎么回事?你丫的有没有测试过啊? 大家一起写个项目, ...
- SpringMVC中异常处理详解
Spring MVC处理异常最基本的就是HandlerExceptionResolver这个接口,先看张图 分析上图可以轻松总结出,spring mvc里有三种异常处理方法: 1.使用官方提供的简单异 ...
- storm配置:如何解决worker进程内存过小的问题
问题导读1.如何设置storm内存?2.如果没有配置文件的情况下,该如何配置一些参数?3.通过哪个参数可以配置内存? Storm中真正干活的是各个worker,而worker由supervisor负责 ...
- Android 权限表
String ACCESS_CHECKIN_PROPERTIES 同意在登入数据库的时候读写当中的属性表,并上传改变的值 String ACCESS_COARSE_LOCATION 同意应用訪问范围( ...
- word2vec中文类似词计算和聚类的使用说明及c语言源代码
word2vec相关基础知识.下载安装參考前文:word2vec词向量中文文本相似度计算 文件夹: word2vec使用说明及源代码介绍 1.下载地址 2.中文语料 3.參数介绍 4.计算相似词语 5 ...
- cocos2d-x开发记录:二,基本概念(动作,动画,坐标系统)
既然我们选择用cocos2d,那么他里面的一些基本概念我们肯定是要熟悉下的,以下资料来源于官网,英语好的可以直接去官网看. 一.Actions(动作) 动作都由于CCNode对象发出.这些动作通常修改 ...