天天看點

java 中多線程的同步函數的運用

java中實作同步的兩種方式:syschronized和lock的差別和聯系

java中同步與異步 

/*
 * 需求:
 * 銀行有一個金庫
 * 有兩個儲戶,分别存300元。每次存100 , 存三次
 * 
 * 這個是有線程問題的,
 * 
 * 我們應該通過下邊的三個方法來查找問題
 * 1.明确哪些代碼是多線程運作的代碼
 * 2.明确共享資料
 * 3.明确多線程運作代碼中哪些是操作共享資料的
 */

class Bank
{
  private int sum;
   public synchronized void   add (int n)
{
sum = sum + n;
try {Thread.sleep (10);}catch (Exception e){}
System.out.println ("sum="+ sum);
}
}

class Cus implements Runnable
{
    private Bank bank = new Bank ();
    public void run(){
        for (int x=0; x<3;x++){
            bank.add(100);
            
        }
        
    }
}
public class BankDemo {

    public static void main(String[] args) {
        
Cus cus = new Cus ();
Thread t1 = new Thread (cus);
Thread t2 = new Thread (cus);
t1.start();
t2.start();

    }

}
           

上邊代碼中的synchorinized 關鍵字 是可以放到函數前邊的,這就叫做同步函數 跟下邊的用法是一個作用

Object obj = new Object ();

Synchronized (obj) {

//需要同步的代碼塊

}

上邊的代碼的例子中的鎖使用的對象其實就是自己本身this,在多線程操作中為了讓線程安全,必須使用同一把鎖

如果同步函數被static 修飾,那麼就不是this了 因為靜态方法中沒有this 方法

靜态進記憶體是,記憶體中沒有本類對象,但是一定有該類對應的位元組碼檔案對象,叫做類名.class 該對象的類型是Class

靜态的同步方法是 使用的鎖是該方法坐在類的位元組碼檔案對象。類名.class

l例如

class Ticket implements Runnable
{
     private  static int tick = 100;
     boolean flag = true;
     Object obj = new Object();
     public void run (){

         if (flag){
         while (true){

             synchronized(Ticket.class){
                if (tick > 0){
                    try {
                        Thread.sleep (10);
                    }
                    catch (Exception a)
                    {


                    }
                    System.out.println(Thread.currentThread().getName()+"sale:"+tick--);
                }
             }

            }
     }else
         while (true)
         show();
     }
         public static synchronized void show()
     {

         if (tick > 0){
                try {
                    Thread.sleep (10);
                }
                catch (Exception a)
                {


                }
                System.out.println(Thread.currentThread().getName()+"sale:"+tick--);
            }
     }
     }



public class ThreadDemo {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        Ticket t = new Ticket ();
        Thread t1 = new Thread (t);
        Thread t2 = new Thread (t);
//        Thread t3 = new Thread (t);
//        Thread t4 = new Thread (t);
        t1.start();
        t2.start();
//        t3.start();
//        t4.start();

    }

}