什么是“线程同步” ?
所谓线程同步就是若干个线程都需要使用一个 synchronized(同步)修饰的方法,当一个线程使用synchronized方法时,其他线程想使用这个synchronized方法时就必须等待,直到这个线程使用完该 synchronized 方法。
在下面的例子中有两个线程,会计和出纳,他俩共同拥有一个账本,她俩都可以使用saveOrTake(int amount)方法对账本进行访问,会计使用saveOrTake(int mount)方法时,向账本上写入存钱记录;出纳使用saveOrTake(int amount)向账本写入取钱记录。因此,当会计使用saveOrTake时,出纳被禁止使用,反之亦然。
原文:http://www.bcoder.cn/?p=777
线程同步例子
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
/* Bank.java*/
package cn.bcoder ; public class Bank implements Runnable { //实现Runnable接口 int money ; public void setMoney ( int n ) { money =n ; } public void run ( ) { //重写Runnbale接口中的abstract方法 if ( Thread. currentThread ( ). getName ( ). equals ( "会计" ) ) //获取当前线程的名字 saveOrTake ( 300 ) ; //调用synchronized修饰的方法,实现进程同步 else if ( Thread. currentThread ( ). getName ( ). equals ( "出纳" ) ) saveOrTake ( 150 ) ; } public synchronized void saveOrTake ( int amount ) { if ( Thread. currentThread ( ). getName ( ). equals ( "会计" ) ) { for ( int i = 0 ;i <= 3 ;i ++ ) //将所有的钱分三次存入 { money =money +amount / 3 ; System. out. println ( Thread. currentThread ( ). getName ( ) + "存入" +amount / 3 + ",账上有" +money + "万,休息一下在存." ) ; try { Thread. sleep ( 3000 ) ; //线程休眠3s } catch ( InterruptedException e ) { // 抛出异常 } } } else if ( Thread. currentThread ( ). getName ( ). equals ( "出纳" ) ) { for ( int i = 0 ;i <= 3 ;i ++ ) { money =money -amount / 3 ; System. out. println ( Thread. currentThread ( ). getName ( ) + "取出" +amount / 3 + ",账上有" +money + "万,休息一下在取." ) ; try { Thread. sleep ( 3000 ) ; } catch ( InterruptedException e ) { } } } } } |
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
/*ThreadDemo.java*/
package cn.bcoder ; public class ThreadDemo { public static void main ( String args [ ] ) { Bank bank = new Bank ( ) ; bank. setMoney ( 500 ) ; Thread accountant ; //会计线程 Thread cashier ; //出纳线程 accountant = new Thread (bank ) ; cashier = new Thread (bank ) ; accountant. setName ( "会计" ) ; //设置线程的名字 cashier. setName ( "出纳" ) ; accountant. start ( ) ; //启动线程 cashier. start ( ) ; } } |