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网站>>
------------------作者 龚细军