Java多线程使用Synchronized需注意锁的永远是对象
来源:互联网 发布:淘宝优惠券如何领取 编辑:程序博客网 时间:2024/06/01 07:40
最近工作室要给大一刚进来工作室的新生进行Java培训,就把Java的只是重新拿起来复习整理了一遍,一直很忙就一直没有写到博客。
在复习Java多线程这里,在处理线程同步时用到了synchronized,也许是太久没有使用线程,出现了下面的问题(挺菜的问题,不过居然困惑了很久,所以记下来了):
public class TestSynchronized{
/** * @param args */ public static void main(String[] args){ MyBank mb1 = new MyBank(); MyBank mb2 = new MyBank(); mb1.start(); mb2.start(); }
}
class MyBank extends Thread{
private static Integer total = 2000;public void run(){ get1500Dollar();}public synchronized void get1500Dollar(){ if(total > 1500){ times ++; System.out.println("第" + times + "次取出1500刀: 成功!"); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } total -= 1500; }else{ times ++; System.out.println("第" + times + "次取出1500刀: 失败!"); }}
}
这段代码本来是期望能够把让get1500Dollar这个方法在被线程mb1访问到后就不能够被mb2访问到的,结果希望是:
第1次取出1500刀:成功! 第2次取出1500刀:失败!
然而,事实是:
第1次取出1500刀:成功! 第2次取出1500刀:成功!
想了很久。。。后来写了个更简单的代码:
public class TestSyc{
public static void main(String[] args){ Example example = new Example(); Thread t1 = new Thread1(example); Thread t2 = new Thread1(example); t1.start(); t2.start();}
}
class Example{
public synchronized void execute(){ for (int i = 0; i < 10; ++i) { try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Hello: " + i); }}
}
class Thread1 extends Thread
{
private Example example;public Thread1(Example example){ this.example = example;}@Overridepublic void run(){ example.execute();}
}
这时,我才想起,synchronized加锁永远都是对对象加锁这一句话,这才理清了思路,对于第二个程序,Example类里面的方法execute加了synchronized之后,t1调用了这个方法后,就对获得这个方法的对象进行了加锁,即对new出来的example整个对象进行加锁了,所以t2想要去通过example访问到execute这个方法就是不可能的了。这个锁会对对象的所有成员变量与方法起作用,也会对这个对象所属类的静态域以及静态方法起作用;但不会由锁住同一个类实例化出来的对象的成员变量和非静态方法。其他由然后回到第一个程序,我是把get1500Dollar方法放在了我的MyBank这个线程类里面,我实例化了mb1,和mb2两个实例,他们的非静态方法并不会互相影响,所以我mb1调用了get1500Dollar时是锁住了mb1这个对象,而我mb2调用的get1500Dollar方法则是mb2自己的方法,所以当然可以被正常访问。
因此,解决方法就是:
1. 把get1500Dollar声明为static,即静态方法;
2. 使用synchronized块,锁住MyBank里面的静态变量total,如下:
public void get1500Dollar(){ synchronized (total) { if(total > 1500){ times ++; System.out.println("第" + times + "取出1500刀: 成功!"); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } total -= 1500; }else{ times ++; System.out.println("第" + times + "取出1500刀: 失败!"); } }}
- Java多线程使用Synchronized需注意锁的永远是对象
- Java多线程Synchronized的注意细节
- Java多线程Synchronized的注意细节
- Java多线程Synchronized的注意细节
- Java多线程----java 对象锁(synchronized/lock)
- Java中synchronized的使用注意
- 跟着实例学习java多线程2-synchronized锁住的是对象还是代码
- java多线程之synchronized和锁对象
- JAVA多线程之synchronized,对象锁,类锁
- 多线程 锁 synchronized 的使用
- Java多线程同步 synchronized 关键字的使用
- Java多线程之synchronized的使用技巧
- 从头认识多线程-2.11 通过同步代码块证明synchronized标记的是对象锁
- Java多线程的线程同步需要注意的地方synchronized与static synchronized区别
- java 使用synchronized关键字锁定的对象
- java 多线程锁synchronized
- 使用synchronized的注意点
- java多线程-synchronized对象和方法的区别
- poj_1681_高斯消元
- 走在看不清的路上
- [数学] AOJ 0009 素数筛选 Prime Number
- JAVA基础之继承
- ios自定义导航控制器转场动画
- Java多线程使用Synchronized需注意锁的永远是对象
- 解压后的eclipse,把exe文件复制到桌面,但是不能打开?的解决之道
- wyh2000 and pupil
- 【JAVA基础】父类类型做形参
- 【扫盲贴】浅谈38K红外发射接受编码
- JSP/SERVLET入门教程--Servlet 使用入门
- 随笔 2015 7 20
- sun.jnu.encoding
- 玩转iOS 9的UIDynamics