成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

java-實(shí)戰(zhàn)java高并發(fā)程序設(shè)計(jì)-ch3JDK并發(fā)包

fox_soyoung / 1504人閱讀

摘要:并發(fā)包參考多線程的同步協(xié)助同步控制擴(kuò)展功能重入鎖之前重入鎖性能好于但開始優(yōu)化現(xiàn)在二者的性能相差不大。倒計(jì)時(shí)器的擴(kuò)展循柵欄。做好異常處理工作。線程池的內(nèi)部實(shí)現(xiàn)該部分待看書

JDK 并發(fā)包

參考:> https://github.com/chengbingh...

3.1 多線程的同步協(xié)助:同步控制

3.1.1 synchronized 擴(kuò)展功能:重入鎖
jdk1.5之前重入鎖ReentrantLook性能好于synchronized, 但jdk1.6 開始優(yōu)化ReentrantLook, 現(xiàn)在二者的性能相差不大。

/**
 * @author ChengBing Han
 * @date 21:50  2018/6/23
 * @description
 */
public class ReentrantLockTest {
    static ReentrantLock reentrantLock = new ReentrantLock();
    static final Object obj = new Object();
    public static void main(String[] args) throws InterruptedException {

        final Thread t1 = new Thread(new Runnable() {
            public void run() {
                System.out.println("T1 lock1");
                reentrantLock.lock();
                System.out.println("T1 lock2");
                reentrantLock.lock();
                System.out.println("T1 unlock1");

                reentrantLock.unlock();
                System.out.println("T1 unlock2");
                reentrantLock.unlock();
            }
        });


        final Thread t2 = new Thread(new Runnable() {
            public void run() {
                synchronized (obj){
                    System.out.println("t2 lock1");
                    synchronized (obj){
                        System.out.println("t2 lock2 ");

                    }
                }
                System.out.println("t2 end");
            }

        });

        System.out.println("lock============");
        t1.start();
        Thread.sleep(1000);
        System.out.println("syschronized==================");
        t2.start();


    }


}

輸出:
lock============
T1 lock1
T1 lock2
T1 unlock1
T1 unlock2
syschronized==================
t2 lock1
t2 lock2 
t2 end

中斷響應(yīng)

public class Interrupted implements Runnable {
    private  Integer state = 0;

    public Interrupted() {
    }

    public Interrupted(Integer state) {
        this.state = state;
    }
   static ReentrantLock reentrantLock1 = new ReentrantLock();
   static ReentrantLock reentrantLock2 = new ReentrantLock();

    public void run() {

        try {
            if(state == 1) {
                reentrantLock1.lockInterruptibly();
                System.out.println("state1===lock1");
                Thread.sleep(1000);
                reentrantLock2.lockInterruptibly();
                System.out.println("state1===lock2");

            }else if(state == 2){
                reentrantLock2.lockInterruptibly();
                System.out.println("state2===lock2");
                Thread.sleep(1000);

                reentrantLock1.lockInterruptibly();
                System.out.println("state2===lock1");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            if(reentrantLock1.isHeldByCurrentThread()){
                reentrantLock1.unlock();
            }
            if(reentrantLock2.isHeldByCurrentThread()){
                reentrantLock2.unlock();
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        final Interrupted r1 = new Interrupted(1);
        final Interrupted r2 = new Interrupted(2);
        final Thread t1 = new Thread(r1);
        final Thread t2 = new Thread(r2);

        t1.start();
        Thread.sleep(100);
        t2.start();
        Thread.sleep(5000);

        t2.interrupt();
    }
}
輸出
state1===lock1
state2===lock2
java.lang.InterruptedException
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireInterruptibly(AbstractQueuedSynchronizer.java:898)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1222)
    at java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:335)
    at com.hcb.thread.c3_1_retrantlookinterrupted.Interrupted.run(Interrupted.java:39)
    at java.lang.Thread.run(Thread.java:748)
state1===lock2

鎖申請(qǐng)等待限時(shí)
一個(gè)鎖只能鎖住某個(gè)時(shí)間段

public class TimeLock implements Runnable{

    static ReentrantLock reentrantLock = new ReentrantLock();
    public void run() {

        try {
            if(reentrantLock.tryLock(3, TimeUnit.SECONDS)){
                System.out.println(Thread.currentThread().getName() + " run");
                Thread.sleep(6000);

            }else {
                System.out.println(Thread.currentThread().getName() + "getLock failed");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            //注意finally 這里釋放鎖的方式
            if(reentrantLock.isHeldByCurrentThread()){
                reentrantLock.unlock();
            }
        }


    }
    
    public static void main(String[] args) throws InterruptedException {
        final TimeLock r1 = new TimeLock();

        final Thread thread1 = new Thread(r1);
        thread1.setName("t1");
        thread1.start();
        Thread.sleep(100);

        final TimeLock r2 = new TimeLock();
        final Thread thread2 = new Thread(r2);
        thread2.setName("t2");
        thread2.start();

    }
}

公平鎖

public class FairLock {

    //構(gòu)造函數(shù)為true,表示公平
    static ReentrantLock reentrantLock = new ReentrantLock(true);
    
    public static class ThreadFair implements Runnable {
        public void run() {
            while (true) {
                try {
                    reentrantLock.lockInterruptibly();
                    System.out.println(Thread.currentThread().getName() + "  run  ");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    if (reentrantLock.isHeldByCurrentThread()) {
                        reentrantLock.unlock();
                    }
                }
            }

        }
    }

    public static void main(String[] args) {
       
            final ThreadFair threadFair = new ThreadFair();
            final Thread fairThread1 = new Thread(threadFair, "fairThread1");
            final ThreadFair threadFair2 = new ThreadFair();
            final Thread fairThread2 = new Thread(threadFair2, "fairThread2");

            fairThread1.start();
            fairThread2.start();
            

    }

}

output:
fairThread1  run  
fairThread2  run  
fairThread1  run  
fairThread2  run  
fairThread1  run  
fairThread2  run  
fairThread1  run  
fairThread2  run  
fairThread1  run  
fairThread2  run  
fairThread1  run  
fairThread2  run  
fairThread1  run  
fairThread2  run  

重入鎖的condition條件

Condition條件類似與wait,notify方法
備注:Condition的使用注意
1、必須在lock.lock()
和lock.singXX中使用 await/singXX

2、方法名是await 不是wait,wait 是object的方法

public class ConditionLock {
    static ReentrantLock reentrantLock = new ReentrantLock();
    static Condition condition = reentrantLock.newCondition();


    static class ConditionLockThread implements Runnable {

        public void run() {

            reentrantLock.lock();
            try {
                System.out.println(Thread.currentThread().getName() + " wait...");
                //方法是await不是object的wait
                condition.await();
                System.out.println(Thread.currentThread().getName() + " end wait...");


            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                if(reentrantLock.isHeldByCurrentThread()){
                    reentrantLock.unlock();
                }

            }

        }
    }

    public static void main(String[] args) throws InterruptedException {
        final ConditionLockThread conditionLockThread1 = new ConditionLockThread();
        final Thread thread1 = new Thread(conditionLockThread1, "ConditionLockThread1");

        final ConditionLockThread conditionLockThread2 = new ConditionLockThread();
        final Thread thread2 = new Thread(conditionLockThread2, "ConditionLockThread2");

        thread1.start();

        thread2.start();
        Thread.sleep(1000);
        //必須在 lock.lock/unlock 中間使用
        reentrantLock.lock();
        condition.signalAll();
        reentrantLock.unlock();

    }
}


允許多個(gè)線程同時(shí)訪問 信號(hào)量Semaphore
可以允許n個(gè)線程同時(shí)訪問,結(jié)合公平鎖。

3.1.4 讀寫鎖
ReadWriteLock JDK

/**
 * @author ChengBing Han
 * @date 14:44  2018/7/7
 * @description
 */
public class ReadWriteLockDemo {
    public static ReentrantLock lock = new ReentrantLock();
    private static ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
    public static Lock readLock = reentrantReadWriteLock.readLock();
    public static Lock writeLock = reentrantReadWriteLock.writeLock();
    public static int value;

    private static int index = 0;

    public static Object handleRead(Lock lock) {

        lock.lock();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
        System.out.println("read value is " + value);
        return value;
    }

    public static void handleWrite(Lock lock, int newValue) {
        lock.lock();

        try {
            Thread.sleep(1000);
            value = newValue;
            System.out.println("write value is " + value);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }


    public static void main(String[] args) {


        final long startTime = System.currentTimeMillis();


        final Runnable readRunnable = new Runnable() {
            public void run() {
                handleRead(readLock);
            }
        };


        final Runnable writeRunnable = new Runnable() {
            public void run() {

                handleWrite(writeLock, ++index);
            }
        };

        for (int i = 0; i < 10; i++) {
            final Thread thread = new Thread(readRunnable);
            thread.start();
        }

        for (int i = 0; i < 10; i++) {
            final Thread thread = new Thread(writeRunnable);
            thread.start();

        }

        //為什么要在while中輸出一些東西呢
        //如果還是一個(gè)空的While循環(huán),while 會(huì)被優(yōu)化在-Server模式下
        while (value != 10){
            System.out.print("");
        }

        final long end = System.currentTimeMillis();
        System.out.println("app use :" + (end - startTime)/1000);

    }
}

倒計(jì)時(shí)(線程個(gè)數(shù))器: CountDownLatch
可以讓n線程都完成任務(wù)了,在繼續(xù)執(zhí)行某個(gè)主線程。例如,火箭發(fā)射前有10個(gè)檢查任務(wù),這時(shí)創(chuàng)建10個(gè)線程分別處理十個(gè)任務(wù),再創(chuàng)建一個(gè)發(fā)射火箭的線程,每次完成一個(gè)檢查任務(wù),CountDownLatch 記錄一個(gè),這樣,可以等10個(gè)都完成了,發(fā)射火箭的線程再執(zhí)行。

倒計(jì)時(shí)器的擴(kuò)展:循柵欄。
擴(kuò)展了CountDownLatch,將軍讓10個(gè)士兵為1組, 這樣一組的完成類似于CountDownLatch, 如果與多組就用循環(huán)柵欄。 可以循環(huán)多組。

線程阻塞工具類:LockSupport
提供一些阻塞的功能

3.2 線程復(fù)用:線程池

3.2.1什么是線程池
同數(shù)據(jù)庫連接池
3.3.2不要重復(fù)造輪子:jdk對(duì)線程池的支持

Executors 是什么?
一言蔽之:工廠

Executors的介紹:
/**
 * Factory and utility methods for {@link Executor}, {@link
 * ExecutorService}, {@link ScheduledExecutorService}, {@link
 * ThreadFactory}, and {@link Callable} classes defined in this
 * package. This class supports the following kinds of methods:
 *
 * 
    *
  • Methods that create and return an {@link ExecutorService} * set up with commonly useful configuration settings. *
  • Methods that create and return a {@link ScheduledExecutorService} * set up with commonly useful configuration settings. *
  • Methods that create and return a "wrapped" ExecutorService, that * disables reconfiguration by making implementation-specific methods * inaccessible. *
  • Methods that create and return a {@link ThreadFactory} * that sets newly created threads to a known state. *
  • Methods that create and return a {@link Callable} * out of other closure-like forms, so they can be used * in execution methods requiring {@code Callable}. *
* * @since 1.5 * @author Doug Lea */

線程池說明

固定數(shù)量的線程池
弊端:如果線程池中有5個(gè)任務(wù),第一個(gè)任務(wù)

/**
 * @author ChengBing Han
 * @date 12:19  2018/7/14
 * @description
 */
public class FixThreadPoolTest {
    
    public static class MyTask implements Runnable{
        public void run() {
            final long id = Thread.currentThread().getId();
            System.out.println("當(dāng)前線程的id是: "  + id);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }
    
    public static void main(String[] args) {
        final ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(5);
        for (int i = 0; i < 10; i++) {
            newFixedThreadPool.submit(new MyTask());
        }
    }
}
通過輸出可以看到,10個(gè)任務(wù),用池子中的了5個(gè)線程
**output:**
當(dāng)前線程的id是: 13
當(dāng)前線程的id是: 15
當(dāng)前線程的id是: 16
當(dāng)前線程的id是: 13
當(dāng)前線程的id是: 14
當(dāng)前線程的id是: 17
當(dāng)前線程的id是: 15
當(dāng)前線程的id是: 16
當(dāng)前線程的id是: 13
當(dāng)前線程的id是: 14

異常處理

/**
 * @author ChengBing Han
 * @date 12:19  2018/7/14
 * @description
 */
public class FixThreadPoolTest {

    static boolean flag = true;
    
    public static class MyTask implements Runnable{
        public void run() {
            if(flag){
                flag=false;
                System.out.println("出現(xiàn)異常");
                System.out.println(1/0);
                System.out.println("異常結(jié)束");
            }

            final long id = Thread.currentThread().getId();
            System.out.println("當(dāng)前線程的id是: "  + id);
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }

    public static void main(String[] args) {
        final ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(5);
        for (int i = 0; i < 10; i++) {
            newFixedThreadPool.submit(new MyTask());
        }
        newFixedThreadPool.shutdown();
    }
}


output:
出現(xiàn)異常
當(dāng)前線程的id是: 11
當(dāng)前線程的id是: 14
當(dāng)前線程的id是: 15
當(dāng)前線程的id是: 13
當(dāng)前線程的id是: 12
當(dāng)前線程的id是: 14
當(dāng)前線程的id是: 15
當(dāng)前線程的id是: 11
當(dāng)前線程的id是: 13

**結(jié)論:根據(jù)上述輸出,可以發(fā)現(xiàn),線程次中有10次調(diào)用,某次發(fā)生異常,不會(huì)影響其它的9次**

定時(shí)線程:

/**
 * @author ChengBing Han
 * @date 12:24  2018/7/14
 * @description
 */
public class SheduleThreadPoolTest {
    
    public static class MyTask implements Runnable{

        public void run() {
            System.out.println("Thread is run which  id is : " + Thread.currentThread().getId());
        }
    }

    public static void main(String[] args) {
        final ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5);
        scheduledExecutorService.scheduleAtFixedRate(new MyTask(),10,1,TimeUnit.SECONDS);
    }
}

*注意定時(shí)的這個(gè)線程池和上述的newFixedThreadPool不同,一旦某個(gè)任務(wù)出現(xiàn)調(diào)度異常,那么后面的任務(wù)都不會(huì)再執(zhí)行。==》做好異常處理工作。

*定時(shí)任務(wù)的兩個(gè)方法不同之處在于
scheduleAtFixedRate: 每隔2秒調(diào)度一個(gè)任務(wù),但是一個(gè)任務(wù)的時(shí)間是8秒(大于2秒)那么實(shí)際是8秒調(diào)度一個(gè)任務(wù)。
scheduleWithFixedDelay: 隔2秒調(diào)度一個(gè)任務(wù),但是一個(gè)任務(wù)的時(shí)間是8秒(大于2秒)那么實(shí)際是8+2秒調(diào)度一個(gè)任務(wù)。

3.2.3 線程池的內(nèi)部實(shí)現(xiàn):
該部分待看書

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/71348.html

相關(guān)文章

  • 實(shí)戰(zhàn)Java發(fā)程序設(shè)計(jì)6】挑戰(zhàn)無鎖算法

    摘要:在本例中,講述的無鎖來自于并發(fā)包我們將這個(gè)無鎖的稱為。在這里,我們使用二維數(shù)組來表示的內(nèi)部存儲(chǔ),如下變量存放所有的內(nèi)部元素。為什么使用二維數(shù)組去實(shí)現(xiàn)一個(gè)一維的呢這是為了將來進(jìn)行動(dòng)態(tài)擴(kuò)展時(shí)可以更加方便。 我們已經(jīng)比較完整得介紹了有關(guān)無鎖的概念和使用方法。相對(duì)于有鎖的方法,使用無鎖的方式編程更加考驗(yàn)一個(gè)程序員的耐心和智力。但是,無鎖帶來的好處也是顯而易見的,第一,在高并發(fā)的情況下,它比有鎖...

    zengdongbao 評(píng)論0 收藏0
  • 聊聊面試中關(guān)于發(fā)問題的應(yīng)對(duì)方案

    摘要:這里呢,我直接給出高并發(fā)場(chǎng)景通常都會(huì)考慮的一些解決思路和手段結(jié)尾如何有效的準(zhǔn)備面試中并發(fā)類問題,我已經(jīng)給出我的理解。 showImg(https://segmentfault.com/img/bV7Viy?w=550&h=405); 主題 又到面試季了,從群里,看到許多同學(xué)分享了自己的面試題目,我也抽空在網(wǎng)上搜索了一些許多公司使用的面試題,目前校招和社招的面試題基本都集中在幾個(gè)大方向上...

    xzavier 評(píng)論0 收藏0
  • 【轉(zhuǎn)】成為Java頂尖程序員 ,看這10本書就夠了

    摘要:實(shí)戰(zhàn)高并發(fā)程序設(shè)計(jì)這本書是目前點(diǎn)評(píng)推薦比較多的書,其特色是案例小,好實(shí)踐代碼有場(chǎng)景,實(shí)用。想要學(xué)習(xí)多線程的朋友,這本書是我大力推薦的,我的個(gè)人博客里面二十多篇的多線程博文都是基于此書,并且在這本書的基礎(chǔ)上進(jìn)行提煉和總結(jié)而寫出來的。 學(xué)習(xí)的最好途徑就是看書,這是我自己學(xué)習(xí)并且小有了一定的積累之后的第一體會(huì)。個(gè)人認(rèn)為看書有兩點(diǎn)好處:showImg(/img/bVr5S5);  1.能出版出...

    DTeam 評(píng)論0 收藏0
  • [Java發(fā)-10] ReadWriteLock:快速實(shí)現(xiàn)一個(gè)完備的緩存

    摘要:此時(shí)線程和會(huì)再有一個(gè)線程能夠獲取寫鎖,假設(shè)是,如果不采用再次驗(yàn)證的方式,此時(shí)會(huì)再次查詢數(shù)據(jù)庫。而實(shí)際上線程已經(jīng)把緩存的值設(shè)置好了,完全沒有必要再次查詢數(shù)據(jù)庫。 大家知道了Java中使用管程同步原語,理論上可以解決所有的并發(fā)問題。那 Java SDK 并發(fā)包里為什么還有很多其他的工具類呢?原因很簡(jiǎn)單:分場(chǎng)景優(yōu)化性能,提升易用性 今天我們就介紹一種非常普遍的并發(fā)場(chǎng)景:讀多寫少場(chǎng)景。實(shí)際工作...

    nevermind 評(píng)論0 收藏0
  • 跳槽季如何快速全面復(fù)習(xí)面試題

    摘要:排序算法和集合工具類排序算法和集合工具類。面試官總是問排序算法也不是在難為你,而是在考察你的編程功底。你首先要理解多線程不僅僅是和那么簡(jiǎn)單,整個(gè)并發(fā)包下面的工具都是在為多線程服務(wù)。 去年的這個(gè)時(shí)候樓主通過兩個(gè)月的復(fù)習(xí)拿到了阿里巴巴的 offer,有一些運(yùn)氣,也有一些心得,借著跳槽季來臨特此分享出來。簡(jiǎn)單梳理一下我的復(fù)習(xí)思路,同時(shí)也希望和大家一起交流討論,一起學(xué)習(xí),如果不對(duì)之處歡迎指正一...

    keke 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<