本文是学习网络上的文章时的总结,感谢大家无私的分享。
每个方法声明为synchronized关键字是一个临界区,Java只允许一个对象执行其中的一个临界区。
静态方法有不同的行为。只有一个执行线程访问被synchronized关键字声明的静态方法,但另一个线程可以访问该类的一个对象中的其他非静态的方法。 你必须非常小心这一点,因为两个线程可以访问两个不同的同步方法,如果其中一个是静态的而另一个不是。如果这两种方法改变相同的数据,你将会有数据不一致
的错误。
package chapter2; public class Account { private double balance; public double getBalance() { return balance; } public void setBalance(double balance) { this.balance = balance; } public synchronized void addAmount(double amount){ double tmp = balance; try { Thread.sleep(10); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } tmp+=amount; balance = tmp; } public synchronized void subtractAmount(double amount){ double tmp = balance; try { Thread.sleep(10); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } tmp-=amount; balance=tmp; } }
package chapter2; public class Bank implements Runnable{ private Account account; public Bank(Account account) { this.account = account; } @Override public void run() { // TODO Auto-generated method stub for(int i=0;i<100;i++){ account.subtractAmount(1000); } } }
package chapter2; public class Main { /** * <p> * </p> * @author zhangjunshuai * @date 2014-9-11 下午4:49:50 * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub Account account = new Account(); account.setBalance(1000); Company company = new Company(account); Thread companyThread = new Thread(company); Bank bank = new Bank(account); Thread bankThread = new Thread(bank); System.out.printf("Account:Initial balance:%f\n", account.getBalance()); companyThread.start(); bankThread.start(); try { companyThread.join(); bankThread.join(); System.out.printf("Account:Initial balance:%f\n", account.getBalance()); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } }
时间: 2024-11-08 10:39:02