国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Java多線程學(xué)習(xí)(六)Lock鎖的使用

Caicloud / 2020人閱讀

摘要:返回與此鎖相關(guān)聯(lián)的給定條件等待的線程數(shù)的估計(jì)。查詢是否有線程正在等待獲取此鎖。為公平鎖,為非公平鎖線程運(yùn)行了獲得鎖定運(yùn)行結(jié)果公平鎖的運(yùn)行結(jié)果是有序的。

系列文章傳送門:

Java多線程學(xué)習(xí)(一)Java多線程入門

Java多線程學(xué)習(xí)(二)synchronized關(guān)鍵字(1)

java多線程學(xué)習(xí)(二)synchronized關(guān)鍵字(2)

Java多線程學(xué)習(xí)(三)volatile關(guān)鍵字

Java多線程學(xué)習(xí)(四)等待/通知(wait/notify)機(jī)制

Java多線程學(xué)習(xí)(五)線程間通信知識點(diǎn)補(bǔ)充

Java多線程學(xué)習(xí)(六)Lock鎖的使用

Java多線程學(xué)習(xí)(七)并發(fā)編程中一些問題

系列文章將被優(yōu)先更新于微信公眾號“Java面試通關(guān)手冊”,歡迎廣大Java程序員和愛好技術(shù)的人員關(guān)注。

本節(jié)思維導(dǎo)圖:

思維導(dǎo)圖源文件+思維導(dǎo)圖軟件關(guān)注微信公眾號:“Java面試通關(guān)手冊” 回復(fù)關(guān)鍵字:“Java多線程” 免費(fèi)領(lǐng)取。

一 Lock接口 1.1 Lock接口簡介

鎖是用于通過多個線程控制對共享資源的訪問的工具。通常,鎖提供對共享資源的獨(dú)占訪問:一次只能有一個線程可以獲取鎖,并且對共享資源的所有訪問都要求首先獲取鎖。 但是,一些鎖可能允許并發(fā)訪問共享資源,如ReadWriteLock的讀寫鎖。

在Lock接口出現(xiàn)之前,Java程序是靠synchronized關(guān)鍵字實(shí)現(xiàn)鎖功能的。JDK1.5之后并發(fā)包中新增了Lock接口以及相關(guān)實(shí)現(xiàn)類來實(shí)現(xiàn)鎖功能。

雖然synchronized方法和語句的范圍機(jī)制使得使用監(jiān)視器鎖更容易編程,并且有助于避免涉及鎖的許多常見編程錯誤,但是有時您需要以更靈活的方式處理鎖。例如,用于遍歷并發(fā)訪問的數(shù)據(jù)結(jié)構(gòu)的一些算法需要使用“手動”或“鏈鎖定”:您獲取節(jié)點(diǎn)A的鎖定,然后獲取節(jié)點(diǎn)B,然后釋放A并獲取C,然后釋放B并獲得D等。在這種場景中synchronized關(guān)鍵字就不那么容易實(shí)現(xiàn)了,使用Lock接口容易很多。

Lock接口的實(shí)現(xiàn)類:
ReentrantLock , ReentrantReadWriteLock.ReadLock , ReentrantReadWriteLock.WriteLock

1.2 Lock的簡單使用
  Lock lock=new ReentrantLock();
  lock.lock();
   try{
    }finally{
    lock.unlock();
    }

因?yàn)長ock是接口所以使用時要結(jié)合它的實(shí)現(xiàn)類,另外在finall語句塊中釋放鎖的目的是保證獲取到鎖之后,最終能夠被釋放。

注意: 最好不要把獲取鎖的過程寫在try語句塊中,因?yàn)槿绻讷@取鎖時發(fā)生了異常,異常拋出的同時也會導(dǎo)致鎖無法被釋放。

1.3 Lock接口的特性和常見方法

Lock接口提供的synchronized關(guān)鍵字不具備的主要特性:

特性 描述
嘗試非阻塞地獲取鎖 當(dāng)前線程嘗試獲取鎖,如果這一時刻鎖沒有被其他線程獲取到,則成功獲取并持有鎖
能被中斷地獲取鎖 獲取到鎖的線程能夠響應(yīng)中斷,當(dāng)獲取到鎖的線程被中斷時,中斷異常將會被拋出,同時鎖會被釋放
超時獲取鎖 在指定的截止時間之前獲取鎖, 超過截止時間后仍舊無法獲取則返回

Lock接口基本的方法:

方法名稱 描述
void lock() 獲得鎖。如果鎖不可用,則當(dāng)前線程將被禁用以進(jìn)行線程調(diào)度,并處于休眠狀態(tài),直到獲取鎖。
void lockInterruptibly() 獲取鎖,如果可用并立即返回。如果鎖不可用,那么當(dāng)前線程將被禁用以進(jìn)行線程調(diào)度,并且處于休眠狀態(tài),和lock()方法不同的是在鎖的獲取中可以中斷當(dāng)前線程(相應(yīng)中斷)。
Condition newCondition() 獲取等待通知組件,該組件和當(dāng)前的鎖綁定,當(dāng)前線程只有獲得了鎖,才能調(diào)用該組件的wait()方法,而調(diào)用后,當(dāng)前線程將釋放鎖。
boolean tryLock() 只有在調(diào)用時才可以獲得鎖。如果可用,則獲取鎖定,并立即返回值為true;如果鎖不可用,則此方法將立即返回值為false 。
boolean tryLock(long time, TimeUnit unit) 超時獲取鎖,當(dāng)前線程在一下三種情況下會返回: 1. 當(dāng)前線程在超時時間內(nèi)獲得了鎖;2.當(dāng)前線程在超時時間內(nèi)被中斷;3.超時時間結(jié)束,返回false.
void unlock() 釋放鎖。
二 Lock接口的實(shí)現(xiàn)類:ReentrantLock

ReentrantLocksynchronized關(guān)鍵字一樣可以用來實(shí)現(xiàn)線程之間的同步互斥,但是在功能是比synchronized關(guān)鍵字更強(qiáng)大而且更靈活。

ReentrantLock類常見方法:

構(gòu)造方法:

方法名稱 描述
ReentrantLock() 創(chuàng)建一個 ReentrantLock的實(shí)例。
ReentrantLock(boolean fair) 創(chuàng)建一個特定鎖類型(公平鎖/非公平鎖)的ReentrantLock的實(shí)例

ReentrantLock類常見方法(Lock接口已有方法這里沒加上):

方法名稱 描述
int getHoldCount() 查詢當(dāng)前線程保持此鎖定的個數(shù),也就是調(diào)用lock()方法的次數(shù)。
protected Thread getOwner() 返回當(dāng)前擁有此鎖的線程,如果不擁有,則返回 null
protected Collection getQueuedThreads() 返回包含可能正在等待獲取此鎖的線程的集合
int getQueueLength() 返回等待獲取此鎖的線程數(shù)的估計(jì)。
protected Collection getWaitingThreads(Condition condition) 返回包含可能在與此鎖相關(guān)聯(lián)的給定條件下等待的線程的集合。
int getWaitQueueLength(Condition condition) 返回與此鎖相關(guān)聯(lián)的給定條件等待的線程數(shù)的估計(jì)。
boolean hasQueuedThread(Thread thread) 查詢給定線程是否等待獲取此鎖。
boolean hasQueuedThreads() 查詢是否有線程正在等待獲取此鎖。
boolean hasWaiters(Condition condition) 查詢?nèi)魏尉€程是否等待與此鎖相關(guān)聯(lián)的給定條件
boolean isFair() 如果此鎖的公平設(shè)置為true,則返回 true 。
boolean isHeldByCurrentThread() 查詢此鎖是否由當(dāng)前線程持有。
boolean isLocked() 查詢此鎖是否由任何線程持有。
2.1 第一個ReentrantLock程序

ReentrantLockTest.java

public class ReentrantLockTest {

    public static void main(String[] args) {

        MyService service = new MyService();

        MyThread a1 = new MyThread(service);
        MyThread a2 = new MyThread(service);
        MyThread a3 = new MyThread(service);
        MyThread a4 = new MyThread(service);
        MyThread a5 = new MyThread(service);

        a1.start();
        a2.start();
        a3.start();
        a4.start();
        a5.start();

    }

    static public class MyService {

        private Lock lock = new ReentrantLock();

        public void testMethod() {
            lock.lock();
            try {
                for (int i = 0; i < 5; i++) {
                    System.out.println("ThreadName=" + Thread.currentThread().getName() + (" " + (i + 1)));
                }
            } finally {
                lock.unlock();
            }

        }

    }

    static public class MyThread extends Thread {

        private MyService service;

        public MyThread(MyService service) {
            super();
            this.service = service;
        }

        @Override
        public void run() {
            service.testMethod();
        }
    }
}

運(yùn)行結(jié)果:

從運(yùn)行結(jié)果可以看出,當(dāng)一個線程運(yùn)行完畢后才把鎖釋放,其他線程才能執(zhí)行,其他線程的執(zhí)行順序是不確定的。

2.2 Condition接口簡介

我們通過之前的學(xué)習(xí)知道了:synchronized關(guān)鍵字與wait()和notify/notifyAll()方法相結(jié)合可以實(shí)現(xiàn)等待/通知機(jī)制,ReentrantLock類當(dāng)然也可以實(shí)現(xiàn),但是需要借助于Condition接口與newCondition() 方法。Condition是JDK1.5之后才有的,它具有很好的靈活性,比如可以實(shí)現(xiàn)多路通知功能也就是在一個Lock對象中可以創(chuàng)建多個Condition實(shí)例(即對象監(jiān)視器),線程對象可以注冊在指定的Condition中,從而可以有選擇性的進(jìn)行線程通知,在調(diào)度線程上更加靈活

在使用notify/notifyAll()方法進(jìn)行通知時,被通知的線程是有JVM選擇的,使用ReentrantLock類結(jié)合Condition實(shí)例可以實(shí)現(xiàn)“選擇性通知”,這個功能非常重要,而且是Condition接口默認(rèn)提供的。

而synchronized關(guān)鍵字就相當(dāng)于整個Lock對象中只有一個Condition實(shí)例,所有的線程都注冊在它一個身上。如果執(zhí)行notifyAll()方法的話就會通知所有處于等待狀態(tài)的線程這樣會造成很大的效率問題,而Condition實(shí)例的signalAll()方法 只會喚醒注冊在該Condition實(shí)例中的所有等待線程

Condition接口的常見方法:

方法名稱 描述
void await() 相當(dāng)于Object類的wait方法
boolean await(long time, TimeUnit unit) 相當(dāng)于Object類的wait(long timeout)方法
signal() 相當(dāng)于Object類的notify方法
signalAll() 相當(dāng)于Object類的notifyAll方法
2.3 使用Condition實(shí)現(xiàn)等待/通知機(jī)制

1. 使用單個Condition實(shí)例實(shí)現(xiàn)等待/通知機(jī)制:

UseSingleConditionWaitNotify.java

public class UseSingleConditionWaitNotify {

    public static void main(String[] args) throws InterruptedException {

        MyService service = new MyService();

        ThreadA a = new ThreadA(service);
        a.start();

        Thread.sleep(3000);

        service.signal();

    }

    static public class MyService {

        private Lock lock = new ReentrantLock();
        public Condition condition = lock.newCondition();

        public void await() {
            lock.lock();
            try {
                System.out.println(" await時間為" + System.currentTimeMillis());
                condition.await();
                System.out.println("這是condition.await()方法之后的語句,condition.signal()方法之后我才被執(zhí)行");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }

        public void signal() throws InterruptedException {
            lock.lock();
            try {                
                System.out.println("signal時間為" + System.currentTimeMillis());
                condition.signal();
                Thread.sleep(3000);
                System.out.println("這是condition.signal()方法之后的語句");
            } finally {
                lock.unlock();
            }
        }
    }

    static public class ThreadA extends Thread {

        private MyService service;

        public ThreadA(MyService service) {
            super();
            this.service = service;
        }

        @Override
        public void run() {
            service.await();
        }
    }
}

運(yùn)行結(jié)果:

在使用wait/notify實(shí)現(xiàn)等待通知機(jī)制的時候我們知道必須執(zhí)行完notify()方法所在的synchronized代碼塊后才釋放鎖。在這里也差不多,必須執(zhí)行完signal所在的try語句塊之后才釋放鎖,condition.await()后的語句才能被執(zhí)行。

注意: 必須在condition.await()方法調(diào)用之前調(diào)用lock.lock()代碼獲得同步監(jiān)視器,不然會報(bào)錯。

2. 使用多個Condition實(shí)例實(shí)現(xiàn)等待/通知機(jī)制:

UseMoreConditionWaitNotify.java

public class UseMoreConditionWaitNotify {
    public static void main(String[] args) throws InterruptedException {

        MyserviceMoreCondition service = new MyserviceMoreCondition();

        ThreadA a = new ThreadA(service);
        a.setName("A");
        a.start();

        ThreadB b = new ThreadB(service);
        b.setName("B");
        b.start();

        Thread.sleep(3000);

        service.signalAll_A();

    }
    static public class ThreadA extends Thread {

        private MyserviceMoreCondition service;

        public ThreadA(MyserviceMoreCondition service) {
            super();
            this.service = service;
        }

        @Override
        public void run() {
            service.awaitA();
        }
    }
    static public class ThreadB extends Thread {

        private MyserviceMoreCondition service;

        public ThreadB(MyserviceMoreCondition service) {
            super();
            this.service = service;
        }

        @Override
        public void run() {
            service.awaitB();
        }
    }
    
}

MyserviceMoreCondition.java

public class MyserviceMoreCondition {

    private Lock lock = new ReentrantLock();
    public Condition conditionA = lock.newCondition();
    public Condition conditionB = lock.newCondition();

    public void awaitA() {
        lock.lock();
        try {
            System.out.println("begin awaitA時間為" + System.currentTimeMillis()
                    + " ThreadName=" + Thread.currentThread().getName());
            conditionA.await();
            System.out.println("  end awaitA時間為" + System.currentTimeMillis()
                    + " ThreadName=" + Thread.currentThread().getName());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void awaitB() {
        lock.lock();
        try {            
            System.out.println("begin awaitB時間為" + System.currentTimeMillis()
                    + " ThreadName=" + Thread.currentThread().getName());
            conditionB.await();
            System.out.println("  end awaitB時間為" + System.currentTimeMillis()
                    + " ThreadName=" + Thread.currentThread().getName());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void signalAll_A() {
        lock.lock();
        try {            
            System.out.println("  signalAll_A時間為" + System.currentTimeMillis()
                    + " ThreadName=" + Thread.currentThread().getName());
            conditionA.signalAll();
        } finally {
            lock.unlock();
        }
    }

    public void signalAll_B() {
        lock.lock();
        try {        
            System.out.println("  signalAll_B時間為" + System.currentTimeMillis()
                    + " ThreadName=" + Thread.currentThread().getName());
            conditionB.signalAll();
        } finally {
            lock.unlock();
        }
    }
}

運(yùn)行結(jié)果:

只有A線程被喚醒了。

3. 使用Condition實(shí)現(xiàn)順序執(zhí)行

ConditionSeqExec.java

public class ConditionSeqExec {

    volatile private static int nextPrintWho = 1;
    private static ReentrantLock lock = new ReentrantLock();
    final private static Condition conditionA = lock.newCondition();
    final private static Condition conditionB = lock.newCondition();
    final private static Condition conditionC = lock.newCondition();

    public static void main(String[] args) {

        Thread threadA = new Thread() {
            public void run() {
                try {
                    lock.lock();
                    while (nextPrintWho != 1) {
                        conditionA.await();
                    }
                    for (int i = 0; i < 3; i++) {
                        System.out.println("ThreadA " + (i + 1));
                    }
                    nextPrintWho = 2;
                    //通知conditionB實(shí)例的線程運(yùn)行
                    conditionB.signalAll();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        };

        Thread threadB = new Thread() {
            public void run() {
                try {
                    lock.lock();
                    while (nextPrintWho != 2) {
                        conditionB.await();
                    }
                    for (int i = 0; i < 3; i++) {
                        System.out.println("ThreadB " + (i + 1));
                    }
                    nextPrintWho = 3;
                    //通知conditionC實(shí)例的線程運(yùn)行
                    conditionC.signalAll();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        };

        Thread threadC = new Thread() {
            public void run() {
                try {
                    lock.lock();
                    while (nextPrintWho != 3) {
                        conditionC.await();
                    }
                    for (int i = 0; i < 3; i++) {
                        System.out.println("ThreadC " + (i + 1));
                    }
                    nextPrintWho = 1;
                    //通知conditionA實(shí)例的線程運(yùn)行
                    conditionA.signalAll();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        };
        Thread[] aArray = new Thread[5];
        Thread[] bArray = new Thread[5];
        Thread[] cArray = new Thread[5];

        for (int i = 0; i < 5; i++) {
            aArray[i] = new Thread(threadA);
            bArray[i] = new Thread(threadB);
            cArray[i] = new Thread(threadC);

            aArray[i].start();
            bArray[i].start();
            cArray[i].start();
        }

    }
}

運(yùn)行結(jié)果:

通過代碼很好理解,說簡單就是在一個線程運(yùn)行完之后通過condition.signal()/condition.signalAll()方法通知下一個特定的運(yùn)行運(yùn)行,就這樣循環(huán)往復(fù)即可。

注意: 默認(rèn)情況下ReentranLock類使用的是非公平鎖

2.4 公平鎖與非公平鎖

Lock鎖分為:公平鎖非公平鎖。公平鎖表示線程獲取鎖的順序是按照線程加鎖的順序來分配的,即先來先得的FIFO先進(jìn)先出順序。而非公平鎖就是一種獲取鎖的搶占機(jī)制,是隨機(jī)獲取鎖的,和公平鎖不一樣的就是先來的不一定先的到鎖,這樣可能造成某些線程一直拿不到鎖,結(jié)果也就是不公平的了。

FairorNofairLock.java

public class FairorNofairLock {

    public static void main(String[] args) throws InterruptedException {
        final Service service = new Service(true);//true為公平鎖,false為非公平鎖

        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("★線程" + Thread.currentThread().getName()
                        + "運(yùn)行了");
                service.serviceMethod();
            }
        };

        Thread[] threadArray = new Thread[10];
        for (int i = 0; i < 10; i++) {
            threadArray[i] = new Thread(runnable);
        }
        for (int i = 0; i < 10; i++) {
            threadArray[i].start();
        }

    }
    static public class Service {

        private ReentrantLock lock;

        public Service(boolean isFair) {
            super();
            lock = new ReentrantLock(isFair);
        }

        public void serviceMethod() {
            lock.lock();
            try {
                System.out.println("ThreadName=" + Thread.currentThread().getName()
                        + "獲得鎖定");
            } finally {
                lock.unlock();
            }
        }

    }
}

運(yùn)行結(jié)果:

公平鎖的運(yùn)行結(jié)果是有序的。

把Service的參數(shù)修改為false則為非公平鎖

final Service service = new Service(false);//true為公平鎖,false為非公平鎖


非公平鎖的運(yùn)行結(jié)果是無序的。

三 ReadWriteLock接口的實(shí)現(xiàn)類:ReentrantReadWriteLock 3.1 簡介

我們剛剛接觸到的ReentrantLock(排他鎖)具有完全互斥排他的效果,即同一時刻只允許一個線程訪問,這樣做雖然雖然保證了實(shí)例變量的線程安全性,但效率非常低下。ReadWriteLock接口的實(shí)現(xiàn)類-ReentrantReadWriteLock讀寫鎖就是為了解決這個問題。

讀寫鎖維護(hù)了兩個鎖,一個是讀操作相關(guān)的鎖也成為共享鎖,一個是寫操作相關(guān)的鎖 也稱為排他鎖。通過分離讀鎖和寫鎖,其并發(fā)性比一般排他鎖有了很大提升。

多個讀鎖之間不互斥,讀鎖與寫鎖互斥,寫鎖與寫鎖互斥(只要出現(xiàn)寫操作的過程就是互斥的。)。在沒有線程Thread進(jìn)行寫入操作時,進(jìn)行讀取操作的多個Thread都可以獲取讀鎖,而進(jìn)行寫入操作的Thread只有在獲取寫鎖后才能進(jìn)行寫入操作。即多個Thread可以同時進(jìn)行讀取操作,但是同一時刻只允許一個Thread進(jìn)行寫入操作。

3.2 ReentrantReadWriteLock的特性與常見方法

ReentrantReadWriteLock的特性:

特性 說明
公平性選擇 支持非公平(默認(rèn))和公平的鎖獲取方式,吞吐量上來看還是非公平優(yōu)于公平
重進(jìn)入 該鎖支持重進(jìn)入,以讀寫線程為例:讀線程在獲取了讀鎖之后,能夠再次獲取讀鎖。而寫線程在獲取了寫鎖之后能夠再次獲取寫鎖也能夠同時獲取讀鎖
鎖降級 遵循獲取寫鎖、獲取讀鎖再釋放寫鎖的次序,寫鎖能夠降級稱為讀鎖

ReentrantReadWriteLock常見方法:
構(gòu)造方法

方法名稱 描述
ReentrantReadWriteLock() 創(chuàng)建一個 ReentrantReadWriteLock()的實(shí)例
ReentrantReadWriteLock(boolean fair) 創(chuàng)建一個特定鎖類型(公平鎖/非公平鎖)的ReentrantReadWriteLock的實(shí)例

常見方法:
和ReentrantLock類 類似這里就不列舉了。

3.3 ReentrantReadWriteLock的使用

1. 讀讀共享

兩個線程同時運(yùn)行read方法,你會發(fā)現(xiàn)兩個線程可以同時或者說是幾乎同時運(yùn)行l(wèi)ock()方法后面的代碼,輸出的兩句話顯示的時間一樣。這樣提高了程序的運(yùn)行效率。

    private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

    public void read() {
        try {
            try {
                lock.readLock().lock();
                System.out.println("獲得讀鎖" + Thread.currentThread().getName()
                        + " " + System.currentTimeMillis());
                Thread.sleep(10000);
            } finally {
                lock.readLock().unlock();
            }
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

2. 寫寫互斥

把上面的代碼的

lock.readLock().lock();

改為:

lock.writeLock().lock();

兩個線程同時運(yùn)行read方法,你會發(fā)現(xiàn)同一時間只允許一個線程執(zhí)行l(wèi)ock()方法后面的代碼

3. 讀寫互斥

    private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

    public void read() {
        try {
            try {
                lock.readLock().lock();
                System.out.println("獲得讀鎖" + Thread.currentThread().getName()
                        + " " + System.currentTimeMillis());
                Thread.sleep(10000);
            } finally {
                lock.readLock().unlock();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void write() {
        try {
            try {
                lock.writeLock().lock();
                System.out.println("獲得寫鎖" + Thread.currentThread().getName()
                        + " " + System.currentTimeMillis());
                Thread.sleep(10000);
            } finally {
                lock.writeLock().unlock();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

測試代碼:

        Service service = new Service();

        ThreadA a = new ThreadA(service);
        a.setName("A");
        a.start();

        Thread.sleep(1000);

        ThreadB b = new ThreadB(service);
        b.setName("B");
        b.start();

運(yùn)行兩個使用同一個Service對象實(shí)例的線程a,b,線程a執(zhí)行上面的read方法,線程b執(zhí)行上面的write方法。你會發(fā)現(xiàn)同一時間只允許一個線程執(zhí)行l(wèi)ock()方法后面的代碼。記住:只要出現(xiàn)寫操作的過程就是互斥的。

4. 寫讀互斥

和讀寫互斥類似,這里不用代碼演示了。記?。褐灰霈F(xiàn)寫操作的過程就是互斥的。

參考:

《Java多線程編程核心技術(shù)》

《Java并發(fā)編程的藝術(shù)》

如果你覺得博主的文章不錯,歡迎轉(zhuǎn)發(fā)點(diǎn)贊。你能從中學(xué)到知識就是我最大的幸運(yùn)。

歡迎關(guān)注我的微信公眾號:“Java面試通關(guān)手冊”(分享各種Java學(xué)習(xí)資源,面試題,以及企業(yè)級Java實(shí)戰(zhàn)項(xiàng)目回復(fù)關(guān)鍵字免費(fèi)領(lǐng)?。A硗馕覄?chuàng)建了一個Java學(xué)習(xí)交流群(群號:174594747),歡迎大家加入一起學(xué)習(xí),這里更有面試,學(xué)習(xí)視頻等資源的分享。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/69098.html

相關(guān)文章

  • 值得保存的 synchronized 關(guān)鍵字總結(jié)

    摘要:無論是互斥鎖,還是自旋鎖,在任何時刻,最多只能有一個保持者,也就說,在任何時刻最多只能有一個執(zhí)行單元獲得鎖。另外在中引入了自適應(yīng)的自旋鎖。和關(guān)鍵字的總結(jié)推薦一 該文已加入開源文檔:JavaGuide(一份涵蓋大部分Java程序員所需要掌握的核心知識)。地址:https://github.com/Snailclimb... 本文是對 synchronized 關(guān)鍵字使用、底層原理、JD...

    miguel.jiang 評論0 收藏0
  • Java線程學(xué)習(xí)(七)并發(fā)編程中一些問題

    摘要:因?yàn)槎嗑€程競爭鎖時會引起上下文切換。減少線程的使用。舉個例子如果說服務(wù)器的帶寬只有,某個資源的下載速度是,系統(tǒng)啟動個線程下載該資源并不會導(dǎo)致下載速度編程,所以在并發(fā)編程時,需要考慮這些資源的限制。 最近私下做一項(xiàng)目,一bug幾日未解決,總惶恐。一日頓悟,bug不可怕,怕的是項(xiàng)目不存在bug,與其懼怕,何不與其剛正面。 系列文章傳送門: Java多線程學(xué)習(xí)(一)Java多線程入門 Jav...

    yimo 評論0 收藏0
  • Java線程學(xué)習(xí)(七)并發(fā)編程中一些問題

    摘要:相比與其他操作系統(tǒng)包括其他類系統(tǒng)有很多的優(yōu)點(diǎn),其中有一項(xiàng)就是,其上下文切換和模式切換的時間消耗非常少。因?yàn)槎嗑€程競爭鎖時會引起上下文切換。減少線程的使用。很多編程語言中都有協(xié)程。所以如何避免死鎖的產(chǎn)生,在我們使用并發(fā)編程時至關(guān)重要。 系列文章傳送門: Java多線程學(xué)習(xí)(一)Java多線程入門 Java多線程學(xué)習(xí)(二)synchronized關(guān)鍵字(1) java多線程學(xué)習(xí)(二)syn...

    dingding199389 評論0 收藏0
  • 深入理解Java內(nèi)存模型(五)——鎖

    摘要:前情提要深入理解內(nèi)存模型四鎖的釋放獲取建立的關(guān)系鎖是并發(fā)編程中最重要的同步機(jī)制。鎖內(nèi)存語義的實(shí)現(xiàn)本文將借助的源代碼,來分析鎖內(nèi)存語義的具體實(shí)現(xiàn)機(jī)制。請看下篇深入理解內(nèi)存模型六 前情提要 深入理解Java內(nèi)存模型(四)—— volatile 鎖的釋放-獲取建立的happens before 關(guān)系 鎖是java并發(fā)編程中最重要的同步機(jī)制。鎖除了讓臨界區(qū)互斥執(zhí)行外,還可以讓釋放鎖的線程向...

    caige 評論0 收藏0
  • Java線程學(xué)習(xí)(二)synchronized關(guān)鍵字(1)

    摘要:轉(zhuǎn)載請備注地址多線程學(xué)習(xí)二將分為兩篇文章介紹同步方法另一篇介紹同步語句塊。如果兩個線程同時操作對象中的實(shí)例變量,則會出現(xiàn)非線程安全,解決辦法就是在方法前加上關(guān)鍵字即可。 轉(zhuǎn)載請備注地址: https://blog.csdn.net/qq_3433... Java多線程學(xué)習(xí)(二)將分為兩篇文章介紹synchronized同步方法另一篇介紹synchronized同步語句塊。系列文章傳送門...

    xuxueli 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<