线程同步

1.使用线程同步机制,达到先支出后收入的效果。

  1 public class AccountTest{
  2     
  3     public static void main(String[] args){
  4         final Account acc = new Account("John", 1000.0f);
  5         acc.setWait(false);
  6         
  7         DepositWorkerThread depositThread = new DepositWorkerThread("收入操作线程:", acc);
  8         WithdrawWorkerThread withdrawThread = new WithdrawWorkerThread("支出操作线程:", acc);
  9         
 10         depositThread.start();
 11         withdrawThread.start();
 12         
 13         // 让当前线程进行等待,上面两个线程执行完毕
 14         try {
 15             depositThread.join();
 16             withdrawThread.join();
 17         } catch (InterruptedException e) {
 18             e.printStackTrace();
 19         }
 20         System.out.println(Thread.currentThread().getName() + ": " + acc.getBalance());
 21     }
 22     
 23     public static void RandomSleep(){
 24         Random random = new Random();
 25         try {
 26             Thread.sleep(random.nextInt(3000));
 27         } catch (InterruptedException e) {
 28             e.printStackTrace();
 29         }
 30     }
 31 }
 32 
 33 /**
 34  * 使用线程同步机制,达到先支出收入的效果。
 35  */
 36 // 对账户收入进行操作的线程
 37 class DepositWorkerThread extends Thread{
 38     
 39     private Account account;
 40     
 41     public DepositWorkerThread(String name, Account account){
 42         this.setName(name);
 43         this.account = account;
 44     }
 45     
 46     @Override
 47     public void run() {
 48         
 49         // 准备工作,耗时
 50         AccountTest.RandomSleep();
 51         
 52         synchronized (account) {
 53                 try {
 54                     if(!account.isWait()){
 55                         account.wait();
 56                     }
 57                     account.deposit(100.0f);
 58                     System.out.println(Thread.currentThread().getName() + ": " + this.account.getBalance());
 59                 } catch (InterruptedException e) {
 60                     e.printStackTrace();
 61                 }
 62         }
 63     }
 64 }
 65 
 66 // 对账户支出进行操作的线程
 67 class WithdrawWorkerThread extends Thread{
 68     
 69     private Account account;
 70     
 71     public WithdrawWorkerThread(String name, Account account){
 72         this.setName(name);
 73         this.account = account;
 74     }
 75     
 76     @Override
 77     public void run() {
 78         
 79         // 准备工作,耗时
 80         AccountTest.RandomSleep();
 81         
 82         synchronized (account) {
 83                 account.withdraw(100.0f);
 84                 System.out.println(Thread.currentThread().getName() + ": " + this.account.getBalance());
 85                 account.setWait(true);
 86                 account.notify();
 87         }
 88     }
 89 }
 90 
 91 
 92 class Account {
 93     String name;
 94     float amount;
 95     boolean isWait;
 96     
 97     public boolean isWait() {
 98         return isWait;
 99     }
100 
101     public void setWait(boolean isWait) {
102         this.isWait = isWait;
103     }
104 
105     public Account(String name, float amount) {
106         this.name = name;
107         this.amount = amount;
108     }
109 
110     // 收入
111     public void deposit(float amt) {
112         float tmp = amount;
113         tmp += amt;
114         
115         try {
116             Thread.sleep(100);//模拟其它处理所需要的时间,比如刷新数据库等
117         } catch (InterruptedException e) {
118             e.printStackTrace();
119         }
120         
121         amount = tmp;
122     }
123 
124     // 支出
125     public void withdraw(float amt) {
126         float tmp = amount;
127         tmp -= amt;
128 
129         try {
130             Thread.sleep(100);//模拟其它处理所需要的时间,比如刷新数据库等
131         } catch (InterruptedException e) {
132             e.printStackTrace();
133         }
134 
135         amount = tmp;
136     }
137 
138     public float getBalance() {
139         return amount;
140     }
141 }

 2. 使用线程同步机制,达到先收入后支出的效果。

  1 public class AccountTest{
  2     
  3     public static void main(String[] args){
  4         final Account acc = new Account("John", 1000.0f);
  5         acc.setWait(false);
  6         
  7         DepositWorkerThread depositThread = new DepositWorkerThread("收入操作线程:", acc);
  8         WithdrawWorkerThread withdrawThread = new WithdrawWorkerThread("支出操作线程:", acc);
  9         
 10         depositThread.start();
 11         withdrawThread.start();
 12         
 13         // 让当前线程进行等待,上面两个线程执行完毕
 14         try {
 15             depositThread.join();
 16             withdrawThread.join();
 17         } catch (InterruptedException e) {
 18             e.printStackTrace();
 19         }
 20         System.out.println(Thread.currentThread().getName() + ": " + acc.getBalance());
 21     }
 22     
 23     public static void RandomSleep(){
 24         Random random = new Random();
 25         try {
 26             Thread.sleep(random.nextInt(3000));
 27         } catch (InterruptedException e) {
 28             e.printStackTrace();
 29         }
 30     }
 31 }
 32 
 33 /**
 34  * 使用线程同步机制,达到先收入后支出的效果。
 35  */
 36 // 对账户收入进行操作的线程
 37 class DepositWorkerThread extends Thread{
 38     
 39     private Account account;
 40     
 41     public DepositWorkerThread(String name, Account account){
 42         this.setName(name);
 43         this.account = account;
 44     }
 45     
 46     @Override
 47     public void run() {
 48         
 49         // 准备工作,耗时
 50         AccountTest.RandomSleep();
 51         
 52         synchronized (account) {
 53             account.deposit(100.0f);
 54             System.out.println(Thread.currentThread().getName() + ": " + this.account.getBalance());
 55             account.setWait(true);
 56             account.notify();
 57         }
 58     }
 59 }
 60 
 61 // 对账户支出进行操作的线程
 62 class WithdrawWorkerThread extends Thread{
 63     
 64     private Account account;
 65     
 66     public WithdrawWorkerThread(String name, Account account){
 67         this.setName(name);
 68         this.account = account;
 69     }
 70     
 71     @Override
 72     public void run() {
 73         
 74         // 准备工作,耗时
 75         AccountTest.RandomSleep();
 76         
 77         synchronized (account) {
 78             try {
 79                 if(!account.isWait()){
 80                     account.wait();
 81                 }
 82                 account.withdraw(100.0f);
 83                 System.out.println(Thread.currentThread().getName() + ": " + this.account.getBalance());
 84             } catch (InterruptedException e) {
 85                 e.printStackTrace();
 86             }
 87         }
 88     }
 89 }
 90 
 91 
 92 class Account {
 93     String name;
 94     float amount;
 95     boolean isWait;
 96     
 97     public boolean isWait() {
 98         return isWait;
 99     }
100 
101     public void setWait(boolean isWait) {
102         this.isWait = isWait;
103     }
104 
105     public Account(String name, float amount) {
106         this.name = name;
107         this.amount = amount;
108     }
109 
110     // 收入
111     public void deposit(float amt) {
112         float tmp = amount;
113         tmp += amt;
114         
115         try {
116             Thread.sleep(100);//模拟其它处理所需要的时间,比如刷新数据库等
117         } catch (InterruptedException e) {
118             e.printStackTrace();
119         }
120         
121         amount = tmp;
122     }
123 
124     // 支出
125     public void withdraw(float amt) {
126         float tmp = amount;
127         tmp -= amt;
128 
129         try {
130             Thread.sleep(100);//模拟其它处理所需要的时间,比如刷新数据库等
131         } catch (InterruptedException e) {
132             e.printStackTrace();
133         }
134 
135         amount = tmp;
136     }
137 
138     public float getBalance() {
139         return amount;
140     }
141 }

3. 不使用状态位来标志是否需要wait

  1 public class AccountTest{
  2     
  3     public static void main(String[] args){
  4         final Account acc = new Account("John", 1000.0f);
  5 //        acc.setWait(false);
  6         
  7         DepositWorkerThread depositThread = new DepositWorkerThread("收入操作线程:", acc);
  8         WithdrawWorkerThread withdrawThread = new WithdrawWorkerThread("支出操作线程:", acc);
  9         
 10         depositThread.start();
 11         withdrawThread.start();
 12         
 13         // 让当前线程进行等待,上面两个线程执行完毕
 14         try {
 15             depositThread.join();
 16             withdrawThread.join();
 17         } catch (InterruptedException e) {
 18             e.printStackTrace();
 19         }
 20         System.out.println(Thread.currentThread().getName() + ": " + acc.getBalance());
 21     }
 22     
 23     public static void RandomSleep(){
 24         Random random = new Random();
 25         try {
 26             Thread.sleep(random.nextInt(3000));
 27         } catch (InterruptedException e) {
 28             e.printStackTrace();
 29         }
 30     }
 31 }
 32 
 33 /**
 34  * 使用线程同步机制,达到先收入后支出的效果。
 35  */
 36 // 对账户收入进行操作的线程
 37 class DepositWorkerThread extends Thread{
 38     
 39     private Account account;
 40     
 41     public DepositWorkerThread(String name, Account account){
 42         this.setName(name);
 43         this.account = account;
 44     }
 45     
 46     @Override
 47     public void run() {
 48         
 49         // 准备工作,耗时
 50         AccountTest.RandomSleep();
 51         
 52         synchronized (account) {
 53             account.deposit(100.0f);
 54             System.out.println(Thread.currentThread().getName() + ": " + this.account.getBalance());
 55 //            account.setWait(true);
 56             account.notify();
 57         }
 58     }
 59 }
 60 
 61 // 对账户支出进行操作的线程
 62 class WithdrawWorkerThread extends Thread{
 63     
 64     private Account account;
 65     
 66     public WithdrawWorkerThread(String name, Account account){
 67         this.setName(name);
 68         this.account = account;
 69     }
 70     
 71     @Override
 72     public void run() {
 73         
 74         // 准备工作,耗时
 75         AccountTest.RandomSleep();
 76         
 77         synchronized (account) {
 78             try {
 79                 // 不使用状态位,判断是否需要调用 wait方法,就会出问题
 80                 // 例如:收入线程首先执行,则收入线程就调用了 notify 方法
 81                 // 此时,执行到这个方法时,调用 wait 方法。则由于没有线程会调用notify方法了,
 82                 // 则这个线程就不会被执行了,
 83                 // 当然也有可能上面的收入线程 执行完 account.deposit(100.0f); 之后被中断
 84                 // 然后下面的方法被执行,之后这个线程陷入等待状态,则上面的线程的 account.notify(); 得到调用
 85                 // 则下面的方法就返回了,所以,这种不使用状态位的情况下,就会有很多问题
 86 //                if(!account.isWait()){
 87                     account.wait();
 88 //                }
 89                 account.withdraw(100.0f);
 90                 System.out.println(Thread.currentThread().getName() + ": " + this.account.getBalance());
 91             } catch (InterruptedException e) {
 92                 e.printStackTrace();
 93             }
 94         }
 95     }
 96 }
 97 
 98 
 99 class Account {
100     String name;
101     float amount;
102     boolean isWait;
103     
104     public boolean isWait() {
105         return isWait;
106     }
107 
108     public void setWait(boolean isWait) {
109         this.isWait = isWait;
110     }
111 
112     public Account(String name, float amount) {
113         this.name = name;
114         this.amount = amount;
115     }
116 
117     // 收入
118     public void deposit(float amt) {
119         float tmp = amount;
120         tmp += amt;
121         
122         try {
123             Thread.sleep(100);//模拟其它处理所需要的时间,比如刷新数据库等
124         } catch (InterruptedException e) {
125             e.printStackTrace();
126         }
127         
128         amount = tmp;
129     }
130 
131     // 支出
132     public void withdraw(float amt) {
133         float tmp = amount;
134         tmp -= amt;
135 
136         try {
137             Thread.sleep(100);//模拟其它处理所需要的时间,比如刷新数据库等
138         } catch (InterruptedException e) {
139             e.printStackTrace();
140         }
141 
142         amount = tmp;
143     }
144 
145     public float getBalance() {
146         return amount;
147     }
148 }

 

posted @ 2015-06-12 18:01  a ray of sunshine  阅读(172)  评论(0编辑  收藏  举报