java--线程同步

 1 package Test;

 2 

 3 public class Demo9 {

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

 5     TestSync2 tt = new TestSync2();

 6         

 7     //

 8     new Thread(tt).start();

 9     new Thread(tt).start();

10     new Thread(tt).start();

11     new Thread(tt).start();

12 }

13 

14 }

15 class TestSync2 implements Runnable{

16     private int ticket = 20;

17     public void run(){

18         while(true){

19             if(ticket>0){

20                 try{

21                     Thread.sleep(1000);

22                 }catch(Exception e){}

23                 System.out.println(Thread.currentThread().getName()+" 出售票: "+ticket--);

24             }

25         }

26     }

27 }
View Code

此段代码的输出结果是:

  

Thread-3 出售票: 10

Thread-2 出售票: 9

Thread-0 出售票: 8

Thread-1 出售票: 7

Thread-2 出售票: 6

Thread-3 出售票: 5

Thread-0 出售票: 4

Thread-1 出售票: 4

Thread-2 出售票: 3

Thread-3 出售票: 2

Thread-1 出售票: 1

Thread-0 出售票: 1

Thread-3 出售票: 0

Thread-2 出售票: -1

很明显数据结果是不对的,这种意外的结果就是要说的“线程安全”问题,即资源访问的同步性问题。
if(tickets>0)
{
System.out.println(Thread.currentThread().getName()+"出售票"+tickets--);
}
即当一个线程运行到if(tickets>0)后,CPU不去执行其它线程中的、可能影响当前线程中的下一句代码的执行结果的代码块,必须等到下一句执行完后才能去执行其它线程中的有关代码块。这段代码就好比一座独木桥,任何时刻,都只能有一个人在桥上行走,程序中不能有多个线程同时在这两句代码之间执行,这就是线程同步

【同步代码块】

  synchronized(对象){

  需要同步的代码块

}

上面的代码修改

Thread-0 出售票: 10

Thread-3 出售票: 9

Thread-2 出售票: 8

Thread-2 出售票: 7

Thread-2 出售票: 6

Thread-2 出售票: 5

Thread-2 出售票: 4

Thread-1 出售票: 3

Thread-1 出售票: 2

Thread-1 出售票: 1

本次的结果:

while(true){

            synchronized(this){

            if(ticket>0){

                try{

                    Thread.sleep(1000);

                }catch(Exception e){}

                System.out.println(Thread.currentThread().getName()+" 出售票: "+ticket--);

            }

        }

        }
View Code

  代码块同步:只需要将需要同步的代码放入synchronized语句之中,形成同步代码块,在同一时刻只有一个线程可以使用该段代码,只有该线程离开这段代码之后,其他的线程才可以使用该段代码(如果一个对象有多个synchronized方法,只要一个线程访问了其中的一个synchronized方法,其它线程不能同时访问这个对象中任何一个synchronized方法)。


【同步方法】

  除了可以同步代码块之外,也可以同步方法体,只需要在方法的返回类型前面加上synchronized即可。当一个线程使用当前的synchronized方法,其他线程就不可以使用本对象中所有用synchronized修饰的方法,直到一个线程执行完他所进入的方法。

【同步对象】

在整个对象上家锁,即synchronized(对象)。那么其他线程在该类所有的对象上的操作都是加锁的。这种方法往往比较粗暴,在类中只有一个方法加锁,却”屏蔽“了这个对象。

  比较好的做法就会给当前使用的对象加锁。

  synchronized(this)

可以参阅:

http://yamei.blog.51cto.com/4382266/864662

你可能感兴趣的:(java)