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 Runnable 21 { 22 int BrickNumber=0; //码放的砖头的数目 23 public void setBrick(int bricks) 24 { 25 BrickNumber=bricks; 26 } 27 public void run() { 28 // TODO Auto-generated method stub 29 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 block 53 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 Runnable 19 { 20 int BrickNumber=0; //码放的砖头的数目 21 public void setBrick(int bricks) 22 { 23 BrickNumber=bricks; 24 } 25 public void run() { 26 // TODO Auto-generated method stub 27 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 block 50 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网站>>
------------------作者 龚细军