java 线程(四)线程安全 同步方法

package cn.sasa.demo2;

import java.util.concurrent.ExecutionException;

public class ThreadDemo {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        //创建Runnable接口实现类对象
        Ticket t = new Ticket();
        //创建3个Thread类对象,传递Runnable接口实现类
        Thread t0 = new Thread(t);
        Thread t1 = new Thread(t);
        Thread t2 = new Thread(t);
        Thread t3 = new Thread(t);
        
        t0.start();
        t1.start();
        t2.start();
        t3.start();
        /**
          * 线程安全问题一般发生在:
          * 多线程并发访问同一个数据资源
         *  
         *  通过线程休眠,出现了安全问题
         *  
         *   Thread-0 出售第 99
         *   Thread-1 出售第 98
         *   Thread-2 出售第 100
         *   Thread-3 出售第 97
         *   Thread-1 出售第 96
         *   Thread-0 出售第 96
         *   Thread-3 出售第 95
         *   Thread-2 出售第 94
         *   Thread-0 出售第 93
         *   Thread-1 出售第 92
         *   Thread-3 出售第 91
         *   Thread-2 出售第 91
         *   Thread-0 出售第 90
         *   Thread-1 出售第 90
         *   Thread-2 出售第 88
         *   Thread-3 出售第 89
         *   Thread-0 出售第 87
         *   Thread-1 出售第 87 ......
         *   
         *   解决安全问题:
         *   同步代码块
         *   synchronized(任意对象){
         *           线程要操作的共享数据
         *   }
         *   同步代码块中的锁对象可以是任意对象,
         *   但多线程时,要使用同一个锁对象才能够保证线程安全性
         *   
         *   同步方法   在方法声明上加入同步关键字
         *   eg :
         *   private synchronized void func(){
         *       ...
         *   }
         *   同步方法中的对象锁,是本类对象引用 this
         *   如果方法是静态的,锁是本类.class属性
         */
        
        
    }
}
package cn.sasa.demo2;

public class Ticket implements Runnable {
    //定义出售的票源
    private int ticket = 100;
    public static int sum = 100; 
    
    public void run(){
        int flag = 100;
      while(flag > 0){
          //buyTickets();
          buy();
          flag --;
      }
    }
    
    //同步方法 synchronized
    private synchronized void buyTickets() {
        if( ticket > 0){
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+" 出售第 "+ticket--);
          }
    }
    
    private static synchronized void buy() {
        if( sum > 0){
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+" 还剩下。。。 "+sum--);
          }
    }
    
}
原文地址:https://www.cnblogs.com/SasaL/p/10193949.html