首页 > 代码库 > java SE学习之线程同步(详细介绍)
java SE学习之线程同步(详细介绍)
java程序中可以允许存在多个线程,但在处理多线程问题时,必须注意这样一个问题:
当两个或多个线程同时访问同一个变量,并且一些线程需要修改这个变量时,那么这个程序是该如何执行?
也就是先访问这个变量还是先修改这个变量.
在学习线程的这段时间里,我也一直被这个问题所困扰!但是今天终于算是搞明白了.
于是将这些好的列子一一列举出来,分享一下.
(1)什么是线程同步 ?
线程同步是所有的线程同时段同时运行吗? 回答是: “当然不是”,
那么什么是线程同步勒? 线程同步就是若干个线程都需要使用一个synchronized(同步的意思)修饰的方法,即程序中的若干个
线程都需要使用一个方法,而这个方法用synchronized给与了修饰。同时多个线程调用synchronized方法必须要遵守同步机制(引自《java 2 使用教程》)
而所说的同步机制其实就是: 当一个线程在使用synchronized方法时,其他线程得等到这个使用完这个synchronized方法时才可以去使用。好比一个队列,要等到前面一个完成了,下面一个才可以继续的意思..可见线程同步,并非我们所的所有线程同时段执行同一个事件、
(2)举列子: 在一个工地上,有两个人分别为甲和乙 ,甲负责搬砖,乙负责砌墙。甲要保证乙时刻都有砖可以砌墙.......
(每一个程序员,都是上辈子折了翅膀的天使!,搬砖的也是,砌砖的也是,呜呜呜呜)。
1 //package DEMO; 2 3 public class chenxiyuan { 4 5 public static void main(String args []) 6 { 7 WorkPlace worker ; 8 worker = new WorkPlace(); 9 worker.setBrick(30); //假设刚开始的时候有30块砖10 Thread jiawork ,yiwork;11 jiawork =new Thread(worker); // 组合12 yiwork = new Thread(worker);13 jiawork.setName("搬砖工");14 jiawork.start();15 yiwork.setName("砌砖工");16 yiwork.start();17 }18 }19 20 class WorkPlace implements Runnable21 {22 int BrickNumber=0; //码放的砖头的数目23 public void setBrick(int bricks)24 {25 BrickNumber=bricks;26 }27 public void run() {28 // TODO Auto-generated method stub29 String name = Thread.currentThread().getName();30 31 if(name.equals("搬砖工")) ;32 else 33 ;34 }35 //使用synchronized修饰方法36 public synchronized void WORK(int bricks)37 {38 String name = Thread.currentThread().getName();39 if(name.equals("搬砖工"))40 {41 while(BrickNumber<100&&BrickNumber>=0)42 {43 System.out.println("我呵了个呵 ,距离休息还差: "+(100-44 45 BrickNumber)+"块砖 !");46 System.out.println("奶奶的,工头不再,赶紧头下懒.....47 48 (*^__^*) !");49 try {50 Thread.sleep(500);51 } catch (InterruptedException e) {52 // TODO Auto-generated catch block53 e.printStackTrace();54 }55 56 BrickNumber+=bricks;57 }58 System.out.println("哇咔咔,终于忙完了!");59 }60 else 61 {62 System.out.println("------又要开始砌砖了!呜 呜 呜 -------");63 while(BrickNumber>0)64 {65 System.out.println("距离完工还有: "+BrickNumber+" 块砖没搞完");66 BrickNumber-=bricks;67 }68 System.out.println("忙完咯! 可以去领工资啦! 欧耶.....!");69 }70 } 71 }
效果图:
如果我们去掉synchronized修饰的又会是什么情况勒? :-)
1 public class chenxiyuan { 2 3 public static void main(String args []) 4 { 5 WorkPlace worker ; 6 worker = new WorkPlace(); 7 worker.setBrick(30); //假设刚开始的时候有30块砖 8 Thread jiawork ,yiwork; 9 jiawork =new Thread(worker); // 组合10 yiwork = new Thread(worker);11 jiawork.setName("搬砖工");12 jiawork.start();13 yiwork.setName("砌砖工");14 yiwork.start();15 }16 }17 18 class WorkPlace implements Runnable19 {20 int BrickNumber=0; //码放的砖头的数目21 public void setBrick(int bricks)22 {23 BrickNumber=bricks;24 }25 public void run() {26 // TODO Auto-generated method stub27 String name = Thread.currentThread().getName();28 29 if(name.equals("搬砖工")) WORK(20);30 else WORK(30) ;31 }32 //使用synchronized修饰方法33 public void WORK(int bricks)34 {35 String name = Thread.currentThread().getName();36 if(name.equals("搬砖工"))37 {38 while(BrickNumber<100&&BrickNumber>=0)39 {40 System.out.println("我呵了个呵 ,距离休息还差: "+(100-41 42 BrickNumber)+"块砖 !");43 System.out.println("奶奶的,工头不再,赶紧头下懒.....44 45 (*^__^*) !");46 try {47 Thread.sleep(500);48 } catch (InterruptedException e) {49 // TODO Auto-generated catch block50 e.printStackTrace();51 }52 53 BrickNumber+=bricks;54 }55 System.out.println("哇咔咔,终于忙完了!");56 }57 else 58 {59 System.out.println("------又要开始砌砖了!呜 呜 呜 -------");60 while(BrickNumber>0)61 {62 System.out.println("距离完工还有: "+BrickNumber+" 块砖没搞完");63 BrickNumber-=bricks;64 }65 System.out.println("忙完咯! 可以去领工资啦! 欧耶.....!");66 }67 } 68 }
效果图:
你会发现,第一个同步线程和多线程的差异原来是,上面讲的等一个人全部做完,才轮到下一个人做。
——--------------------------------——参考文献——————————————————————————————————————————
****** 《java 2 程序设计》 ----(第四版)
****** <<csdn网站>>
------------------作者 龚细军