JAVA多线程(3)——如何加锁

1、加锁不正确导致数据不一致:m1执行过程中,m2(未加synchronized)可以执行,因为m2不用获得锁就可以执行

 1 public class TT implements Runnable {
 2     int b = 100;
 3     
 4     public synchronized void m1() throws Exception {
 5         b = 1000;
 6         System.out.println("in m1() before sleep,b="+b);
 7         Thread.sleep(5000);
 8         System.out.println("in m1() after sleep,b="+b);
 9     }
10     
11     public void m2() {
12     //public synchronized void m2() throws Exception {
13         b = 199;
14         System.out.println("in m2(),b="+b);
15     }
16     
17     public void run() {
18         try {
19             m1();
20         } catch (Exception e) {
21             e.printStackTrace();
22         }
23     }
24     
25     public static void main(String[] args) throws Exception {
26         TT tt = new TT();
27         System.out.println("in main() just after new TT(),b=" + tt.b);
28         Thread t = new Thread(tt);
29         t.start();
30         
31         Thread.sleep(1000);  //为了让m1能够执行b=1000的赋值
32         tt.m2();           // 主线程执行m2
33         
34         System.out.println("in main() last,b=" + tt.b);
35     }
36 }

结果:

D:\聚划算\技术部\编程练习\TestThread\Sync>java TT
in main() just after new TT(),b=100
in m1() before sleep,b=1000
in m2(),b=199
in main() last,b=199
in m1() after sleep,b=199  //main线程先于t线程结束吗?

说明:锁定当前对象 只是针对synchronized 这段话,另外的线程完全有可能访问没有锁定的方法(即不带synchronized 的方法)

问题:要保证对资源b的正确访问,需要考虑所有访问b的所有方法,是否需要加同步:加了同步效率可能变低、不加同步可能会出现数据不一致

 

问题:main线程先于t线程结束吗?

解答:会,main方法即使执行完最后的语句,JVM也不会结束该程序,要等到主线程中的所有其它线程都结束之后,才结束该JAVA应用程序

 

2、解决上述访问资源b,数据不一致的问题:把所有访问b的方法加锁,m1执行过程,m2一定执行不了,执行m2时必须要得到当前对象的锁才能执行

 1 public class TT implements Runnable {
 2     int b = 100;
 3     
 4     public synchronized void m1() throws Exception {
 5         b = 1000;
 6         System.out.println("in m1() before sleep,b="+b);
 7         Thread.sleep(5000);
 8         System.out.println("in m1() after sleep,b="+b);
 9     }
10     
11     public synchronized void m2() {
12     //public synchronized void m2() throws Exception {
13         b = 199;
14         System.out.println("in m2(),b="+b);
15     }
16     
17     public void run() {
18         try {
19             m1();
20         } catch (Exception e) {
21             e.printStackTrace();
22         }
23     }
24     
25     public static void main(String[] args) throws Exception {
26         TT tt = new TT();
27         System.out.println("in main() just after new TT(),b=" + tt.b);
28         Thread t = new Thread(tt);
29         t.start();
30         
31         Thread.sleep(1000);  //为了让m1能够执行b=1000的赋值
32         tt.m2();
33         
34         System.out.println("in main() last,b=" + tt.b);
35     }
36 }

结果:

D:\聚划算\技术部\编程练习\TestThread\Sync>java TT
in main() just after new TT(),b=100
in m1() before sleep,b=1000
in m1() after sleep,b=1000  //m1执行完了才会执行m2
in m2(),b=199
in main() last,b=199

 

举例:

如何加锁:——设定同步对象时较麻烦
数据库中的某一个记录,可以改、也可以读,一般情况下哪个方法应该加锁?
(1)读:允许多个线程同时读
(2)改:要加synchronized ,不允许两个线程同时改

 

posted on 2013-10-10 19:22  gogoy  阅读(997)  评论(0编辑  收藏  举报

导航