首页 > 代码库 > java中的线程问题是(四)——线程同步问题

java中的线程问题是(四)——线程同步问题

      多线程的并发,给我们编程带来很多好处,完成更多更有效率的程序。但是也给我们带来线程安全问题。

      解决问题的关键就是要保证容易出问题的代码的原子性,所谓原子性就是指:当a线程在执行某段代码的时候,别的线程必须等到a线程执行完后,它才能执行这段代码。也就是排队一个一个解决。

java处理线程两步的方法非常简单,只需要在需要同步的代码段,用:synchronized(Object){你要同步的代码}即可。

对同步机制的解释:

    java任意类型的对象都有一个标志位,该标志位具有0、1两种状态,其开始状态为1,当某个线程执行了synchronized(Object)语句后,object对象的标志位变为0的状态,直到执行完整个synchronized语句中的代码块后,该对象的标志位又回到1状态。

    当一个线程执行到synchronized(Object)语句的时候,先检查Object对象的标志位,如果为0状态,表明已经有另外的线程正在执行synchronized包括的代码,那么这个线程将暂时阻塞,让出CPU资源,直到另外的线程执行完相关的同步代码,并将Object对象的标志位变为状态,这个线程的阻塞就被取消,线程能继续运行,该线程又将Object的标志位变为0状态,防止其它的线程再进入相关的同步代码块中。

    如果有多个线程因等待同一个对象的标志位面而处于阻塞状态时,当该对象的标志位恢复到1状态时,只会有一个线程能够进入同步代码执行,其它的线程仍处于阻塞的状态。

特别说明:

1、上面所说的标志位用术语讲就是对象锁,文件锁。数据库会有行锁、表锁等

2、synchronized(object)//object(就是对象锁)可以是任意类型对象

3   synchronized也可以修饰方法,当其修饰方法是,对象锁默认为(this)。

售票系统的演示

 1 /**
 2  * 功能:使用线程的注意事项
 3  * 线程并发同步锁synchronized(Object){}的使用
 4  */
 5 public class Thread05 {
 6     public static void main(String[] args) {
 7         //定义一个售票窗口
 8         TicketWindow tw1=new TicketWindow();
 9         
10         //使用三个线程同时启动
11         Thread t1=new Thread(tw1);
12         Thread t2=new Thread(tw1);
13         Thread t3=new Thread(tw1);
14         
15         t1.start();
16         t2.start();
17         t3.start();
18     }
19 }
20 
21 //售票窗口类
22 class TicketWindow implements Runnable {
23     //共有2000张票
24     private int nums=2000;
25     private Dog myDog=new Dog();
26 
27     public void run() {
28         while(true){
29             //出票速度是1秒出一张
30             try {
31                 Thread.sleep(1000);
32             } catch (Exception e) {
33                 e.printStackTrace();
34             }
35 
36             //认为if else要保证其原子性
37             //先判断是否还有票
38             synchronized(myDog){//synchronized(this){}为同步代码块
39                 if(nums>0){
40                     //显示售票信息
41                     //Thread.currentThread().getName()得到当前线程的名字
42                     System.out.println(Thread.currentThread().getName()+"正在售出第"+nums+"张票");
43                     nums--;
44                 }else{
45                     //售票结束
46                     break;
47                 }
48             }
49         }
50     }
51 }

 

java中的线程问题是(四)——线程同步问题