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小结的更多相关文章

  1. 多线程中的synchronized

    synchronized是Java中的关键字,是一种同步锁.它修饰的对象有以下几种: 1. 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码 ...

  2. 多线程中的Lock小结

    出处:http://www.cnblogs.com/DarrenChan/p/6528578.html#undefined 1.lock和synchronized的区别 1)Lock不是Java语言内 ...

  3. java多线程中 volatile与synchronized的区别-阿里面试

    volatile 与 synchronized 的比较(阿里面试官问的问题) ①volatile轻量级,只能修饰变量.synchronized重量级,还可修饰方法 ②volatile只能保证数据的可见 ...

  4. [多线程] 线程中的synchronized关键字锁

    为什么要用锁? 在多线程中,难免会出现在多个线程中对同一个对象的实例变量或者全局静态变量进行并发访问的情况,如果不做正确的同步处理,那么产生的后果就是"脏读",也就是取到的数据其实 ...

  5. java中多线程详解-synchronized

    一.介绍 当多个线程涉及到共享数据的时候,就会设计到线程安全的问题.非线程安全其实会在多个线程对同一个对象中的实例变量进行并发访问时发生,产生的后果就是“脏读”.发生脏读,就是取到的数据已经被其他的线 ...

  6. c#多线程中Lock()关键字的用法小结

    本篇文章主要是对c#多线程中Lock()关键字的用法进行了详细的总结介绍,需要的朋友可以过来参考下,希望对大家有所帮助     本文介绍C# lock关键字,C#提供了一个关键字lock,它可以把一段 ...

  7. 深入理解java中的synchronized关键字

    synchronized 关键字,代表这个方法加锁,相当于不管哪一个线程A每次运行到这个方法时,都要检查有没有其它正在用这个方法的线程B(或者C D等),有的话要等正在使用这个方法的线程B(或者C D ...

  8. BlockingQueue阻塞队列(解决多线程中数据安全问题 可用于抢票,秒杀)

    案例:一个线程类中 private static BlockingQueue<Map<String, String>> dataQueue = new LinkedBlocki ...

  9. java中的synchronized同步代码块和同步方法的区别

    下面这两段代码有什么区别? //下列两个方法有什么区别 public synchronized void method1(){} public void method2(){ synchronized ...

随机推荐

  1. github常见操作和常见错误及其解决办法

    一.常见操作 1. 使用git在本地创建一个项目的过程 $ makdir ~/hello-world //创建一个项目hello-world $ cd ~/hello-world //打开这个项目 $ ...

  2. RabbitMQ与.net core(五) topic类型 与 headers类型 的Exchange

    1.topic类型的Exchange 我们之前说过Topic类型的Exchange是direct类型的模糊查询模式,可以通过routkey来实现模糊消费message,topic的模糊匹配有两种模式: ...

  3. python学习笔记——

    python线程的GIL GIL (全局解释器锁)python --- > 支持多线程 ----> 同步和互斥 --->加锁 --->解释器加锁 ————> 解释器同一时 ...

  4. 查看python selenium 的api

    DOS窗口输入: python -m pydoc -p 4567 python -m pydoc : 打开pydoc模块,pydoc是查看python文档的首选工具 -p 4567: 在4567端口启 ...

  5. 实现 Sunday 算法

    鉴于校园招聘笔试题,有个字符串模式匹配的问题,99+%都是暴力,偶尔一两个写KMP,但是明显是知其表不知其里.期待的 BM算法 或者 Sunday 没有出现!鉴于网友的回复,特此声明:我的代码假定字符 ...

  6. 通向码农的道路(enet开源翻译计划 二)

    QQ 324186207群 enet交流技术,主要是为了研究tcp内部执行机制.欢迎大家增加探讨.小弟水平有限,翻译难免有误. . http://enet.bespin.org 解析enet 双向链表 ...

  7. 局域网不同用户同时登录同一个网站,会出现session乱窜的问题

    出现这种问题的情景再现: 1.有一部分人访问网站会出现session乱窜的问题. 2.这部分人是在同一个局域网中. 3.不同菜单看到的信息是不同人的,或者同一个菜单翻页时有的时候看到的是自己的数据,有 ...

  8. 整理了一份招PHP高级工程师的面试题(转)

    1. 基本知识点 HTTP协议中几个状态码的含义:1xx(临时响应) 表示临时响应并需要请求者继续执行操作的状态代码. 代码   说明 100   (继续) 请求者应当继续提出请求. 服务器返回此代码 ...

  9. jquery中常见问题及解决办法小结

    1 在开发开放聊天室的过程中,遇到使用ajax提交表单插入数据库时会插入两条数据的情况 解决办法,在ajax函数返回后,return false. $("#btn").click( ...

  10. Effective C++ Item 42 了解 typename 的双重意义

    本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:声明 template 參数时,前缀keyword class 和 typename ...