多线程同步代码块

通过分析,发现  打印出了0和,-1等等错误的票,多线程的运行出现了安全问题

问题的原因:当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完另一个线程参与进来执行,导致共享数据的错误

解决办法:对多条操作共享数据的语句,只能让一个线程都执行完,在执行过程中,其他线程不可以参与执行,java对于多线程的安全问题提供了专业的解决方式:就是同步代码块

 

synchronized(对象){
 需要被同步的代码
}

对象如同锁,持有锁的线程可以再同步中执行,没有持有锁的线程即使获取cpu执行权,也进不去,因为没有获取锁

 

同步的前提:
 1.必须有两个或者两个以上的线程,单线程的时候就不用同步了
 2.必须是多个线程同时使用同一个锁

 必须保证同步中只有一个线程在运行

 

好处:解决了线程的安全问题
弊端:消耗了资源,多个线程都要判断锁

 1 public class SynchronizedDemo {

 2     public static void main(String[] args) {

 3         Ticket1 t = new Ticket1();

 4         

 5         Thread d1 = new Thread(t);

 6         Thread d2 = new Thread(t);

 7         Thread d3 = new Thread(t);

 8         Thread d4 = new Thread(t);

 9     

10         d1.start();

11         d2.start();

12         d3.start();

13         d4.start();

14     }

15 }

16 class Ticket1 implements Runnable{

17     private int tick = 50;

18     Object obj = new Object();

19     public void run(){

20         while(true){

21             /*

22             0线程进来执行判断了tick大于0之后,0线程就倒了,其他线程进来执行完代码打印完0号票之后0线程再执行的时候不在判断,直接执行代码了,但是当前的tick变成-1了,这就出现了安全问题了

23             obj相当于一个锁,刚开始是锁是开着的,一个线程进来以后,锁就锁住了,外面的线程进不来

24             只有当进去的线程执行完,出了同步代码块,之后,锁才会打开

25             */

26             synchronized(obj){

27                 if(tick>0){

28                         try{Thread.sleep(10);}catch(Exception e){}//这里要有针对的处理方式}//因为Runnable没有异常,所以不能在run方法中抛出异常,只能try catch

29                         System.out.println(Thread.currentThread().getName()+"........"+tick--);

30                 }

31             }

32         }

33     }

34 }

 

你可能感兴趣的:(线程同步)