线程同步

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 }

 

你可能感兴趣的:(线程同步)