Java中同步機制有一下幾種方式(3種)

線程同步的機制是用來解決線程安全問題的
操作同步代碼時,只能有一個線程參與,其他線程等待。相當於是一個單線程的過程,效率低。

標題1、Java中同步機制有一下幾種方式

1.1、方式一:同步代碼塊(處理實現Runnable安全問題,Thread實現類實現的話,需要加static保證當前對象的唯一性)

synchronized(同步監視器){
//需要被同步的代碼
}
說明: 1、操作共享數據的代碼,即爲需要被同步的代碼
2、共享數據:多個線程共同操作的變量。比如:ticket就是共享數據。
3、同步監視器:俗稱鎖。任何一個類的對象,都可以充當鎖。
要求: 多個線程必須要公用同一把鎖

案例(窗口取票案例):

class Windows implements Runnable{
private int tickets = 100;
private Object ob = new Object(); //線程的同一把鎖,即同一個對象
    @Override
    public void run() {
        while (true) {
            synchronized(ob) {  //通過synchronized來加鎖  
                if (tickets > 0) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + ":買票,票號爲:" + tickets);
                    tickets--;
                } else {
                    break;
                }
            }
        }
    }
}
public class Window {
    public static void main(String[] args) {
        Windows w = new Windows();
        Thread t1 = new Thread(w);
        Thread t2 = new Thread(w);
        Thread t3 = new Thread(w);
      
        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");
        t1.start();
        t2.start();
        t3.start();
    }
}

1.2、方式二:同步方法

關於同步方法總結:
1、同步方法仍然涉及到同步監器,只是不需要我門顯示的聲明。
2、非靜態同步方法,同步監視器是this
靜態的同步方法,同步監視器是:當前類本身
當使用Thread類的子類時,需要把同步方法設置爲static public static synchronized void way()

class Windows implements Runnable{
    private int tickets = 100;
    @Override
    public void run() {
        while (true) {
            way();
        }
    }
    public synchronized void way() {  //通過synchronized來加鎖,代表的是this當前的Windows類
        if (tickets > 0) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + ":買票,票號爲:" + tickets);
            tickets--;
        }
    }
}
public class Window {
    public static void main(String[] args) {
        Windows w = new Windows();
        Thread t1 = new Thread(w);
        Thread t2 = new Thread(w);
        Thread t3 = new Thread(w);
        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");
        t1.start();
        t2.start();
        t3.start();
    }
}

1.3、Lock()鎖 ————JDK5.0新增

import java.util.concurrent.locks.ReentrantLock;
class Windowt implements Runnable {
    private int ticktes = 100;
    private ReentrantLock lock = new ReentrantLock();
    @Override
    public void run() {
        while (true) {
            try{
                //加放鎖
                lock.lock();
                if (ticktes > 0) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "當前的票數爲:" + ticktes);
                    ticktes--;
                } else {
                    break;
                }
            }finally {
                //釋放鎖
                lock.unlock();
            }
        }
    }
}
public class ThreadLock {
    public static void main(String[] args) {
        Windowt window = new Windowt();
        Thread t1 = new Thread(window);
        Thread t2 = new Thread(window);
        Thread t3 = new Thread(window);
        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");
        t1.start();
        t2.start();
        t3.start();
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章