标签:trace star 使用 引入 string 同步机制 成员 name 小例子
关于线程的安全问题,这里举一个很简单的银行取钱的问题:
当两个用户使用同一个账号取钱时,相当于两个线程并发取钱,则可能出现错误。
出现错误的原因是因为run()方法不具有同步安全性。为了解决这个问题,java多线程支持引入同步监视器,使用同步监视器的格式如下:
sysnchronized(boj){
..........
}
其运行逻辑是:加锁>修改>释放锁
synchronized关键字可以修饰方法,代码块,不能修饰构造器,成员变量
如下几种情况会释放同步监视器:
如下几种情况不会释放同步监视器
这里放一个银行取钱的小例子:
package com.tc.test; public class Acount { private String accountNo; private double balance; public Acount(String accountNo, double balance) { super(); this.accountNo = accountNo; this.balance = balance; } public String getAccountNo() { return accountNo; } public void setAccountNo(String accountNo) { this.accountNo = accountNo; } public double getBalance() { return balance; } // public void setBalance(double balance) { // this.balance = balance; // } public synchronized void draw(double drawAmount){ if( balance > drawAmount ){ System.out.println(Thread.currentThread().getName() +"取钱成功"+drawAmount); try{ Thread.sleep(1); } catch(InterruptedException e){ e.printStackTrace(); } //修改余额 balance-=drawAmount; System.out.println("余额为:"+balance); }else{ System.out.println("取钱失败,余额不足!!!"); } } }
package com.tc.test; public class DrawThread extends Thread { private Acount account; private double drawAmount; public DrawThread(String name , Acount account, double drawAmount) { super(name); this.account = account; this.drawAmount = drawAmount; } public void run(){ account.draw(drawAmount); } }
package com.tc.test; public class DrawTest { public static void main(String[] args) { Acount ac=new Acount("123",1000); new DrawThread("第一个",ac,800).start(); new DrawThread("第二个",ac,800).start(); } }
同步锁
从jdk1.5开始,java提供了一种功能更强大的线程同步机制————通过显示定义同步锁对象来实现同步,在这种机制下,同步锁由Lock对象充当。
Lock是控制对个线程对共享资源的进行访问的工具,通常锁提供了对共享资源的独占访问,每次只能有一个线程对lock加锁,线程在访问共享资源之前必须先获得Lock对象
java8新增了新型的StampedLock类,为读写提供了三种锁模式:Writing,ReadOptimistic,Reading 。
死锁
当两个线程互相等待对方释放同步监视器时就会发生死锁,java虚拟机并没有检测,也没有采取措施来处理死锁,一旦出现死锁,整个程序不会发生任何异常,也不会有任何提示,只是所有线程处于阻塞状态。
标签:trace star 使用 引入 string 同步机制 成员 name 小例子
原文地址:http://www.cnblogs.com/cumtlg/p/7608792.html