java骞跺彂缂栫▼涔嬬編-闃呰璁板綍11

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java骞跺彂缂栫▼涔嬬編-闃呰璁板綍11相关的知识,希望对你有一定的参考价值。

鏍囩锛?a href='http://www.mamicode.com/so/1/%e9%80%9f%e5%ba%a6' title='閫熷害'>閫熷害   orm   break   normal   Fix   engine   鍐呭瓨   渚濊禆   闃叉   

java骞跺彂缂栫▼瀹炶返

11.1ArrayBlockingQueue鐨勪娇鐢?/p>

銆€銆€鏈夊叧logback寮傛鏃ュ織鎵撳嵃涓殑ArrayBlockingQueue鐨勪娇鐢?/p>

銆€銆€1銆佸紓姝ユ棩蹇楁墦鍗版ā鍨嬫杩?/p>

銆€銆€銆€銆€鍦ㄩ珮骞跺彂銆侀珮娴侀噺骞朵笖鍝嶅簲鏃堕棿瑕佹眰姣旇緝灏忕殑绯荤粺涓悓姝ユ墦鍗版棩蹇楀湪鎬ц兘涓婂凡缁忔弧瓒充笉浜嗕簡锛岃繖鏄互鍥犱负鎵撳嵃鏈韩鏄渶瑕佸啓纾佺洏鐨勶紝鍐欑鐩樻搷浣滀細鏆傛椂闃诲璋冪敤鎵撳嵃鏃ュ織鐨勪笟鍔$郴缁燂紝杩欎細閫犳垚璋冪敤绾跨▼鐨勫搷搴旀椂闂村鍔犮€?/p>

銆€銆€銆€銆€鎶€鏈浘鐗? src=   ----- 銆嬨€嬨€?img alt="鎶€鏈浘鐗? src="http://image.mamicode.com/info/201908/20190818174637143642.png" width="265" height="193" />

 

銆€銆€銆€銆€寮傛鏃ュ織鎵撳嵃锛屾槸灏嗘墦鍗版棩蹇椾换鍔℃斁鍏ヤ竴涓槦鍒楀悗灏辫繑鍥烇紝鐒跺悗浣跨敤涓€涓嚎绋嬩笓闂ㄤ粠闃熷垪涓幏鍙栨棩蹇椾换鍔★紝骞跺皢鍏跺啓鍏ョ鐩樸€?/p>

 銆€銆€2銆佸紓姝ユ棩蹇楀疄鐜?/p>

銆€銆€銆€涓€鑸儏鍐典笅鐨勫悓姝ユ棩蹇條ogback.xml閰嶇疆濡備笅锛氾紙pattern浼氱壒娈婂畾鍒讹級

<configuration>
  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>myapp.log</file>
    <encoder>
      <pattern>%logger35 - %msg%n</pattern>
    </encoder>
  </appender>

  <root level="DEBUG">
    <appender-ref ref="FILE" />
  </root>
</configuration>

銆€銆€鑰屽紓姝ユ棩蹇楃殑logback.xml閰嶇疆濡備笅锛氬浜嗕釜AsyncAppender閰嶇疆锛岃绫诲氨鏄疄鐜板紓姝ユ棩蹇楃殑鍏抽敭绫?/p>

<configuration>
  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>myapp.log</file>
    <encoder>
      <pattern>%logger35 - %msg%n</pattern>
    </encoder>
  </appender>

  <appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
    <appender-ref ref="FILE" />
  </appender>

  <root level="DEBUG">
    <appender-ref ref="ASYNC" />
  </root>
</configuration>

銆€銆€3銆佸紓姝ユ棩蹇?/p>

銆€銆€绫诲浘锛?/p>

銆€銆€銆€銆€鐢辩被鍥惧彲浠ョ湅鍑猴紝AsyncAppender缁ф壙AsyncAppenderBase绫伙紝瀹炵幇AppenderAttachable鎺ュ彛锛岃€屽叧閿疄鐜板紓姝ユ柟娉曠殑鏄疉syncAppenderBase绫伙紝鍏朵腑blockingQueue鏄湁鐣岀殑闃诲闃熷垪锛宷ueueSize琛ㄧず鏈夌晫闃熷垪鐨勫厓绱犱釜鏁帮紝worker鍒欐槸宸ヤ綔绾跨▼锛屼篃灏辨槸涔熶笉鎵撳嵃鏃ュ織鐨勬秷璐硅€呯嚎绋嬶紝aai鍒欐槸涓€涓猘ppender鐨勮楗板櫒锛岄噷杈瑰瓨鏀剧殑鍚屾鏃ュ織鐨刟ppender锛屽叾涓璦ppenderCount璁板綍aai閲岃竟闄勫姞鐨勫悓姝ppender鐨勪釜鏁帮紙杩欎釜鍜岄厤缃枃浠剁浉瀵瑰簲锛屼竴涓紓姝ョ殑appender瀵瑰簲涓€涓悓姝ョ殑appender锛夛紝neverBlock鐢ㄦ潵鎸囩ず褰撳悓姝ラ槦鍒楀凡婊℃椂鏄惁闃诲鎵撳嵃鏃ュ織绾跨▼锛宒iscardingThreshold鏄竴涓槇鍊硷紝褰撴棩蹇楅槦鍒楅噷杈圭殑绌洪棽鍏冪礌涓暟灏忎簬璇ュ€兼椂锛屾柊鏉ョ殑鏌愪簺绾у埆鐨勬棩蹇楀氨浼氱洿鎺ヨ涓㈠純銆?/p>

銆€銆€鎶€鏈浘鐗? src=

銆€銆€4銆丄syncAppenderBase绫?/p>

銆€銆€浣曟椂鍒涘缓鏃ュ織闃熷垪锛?/p>

public void start() 
        if (isStarted())
            return;
        if (appenderCount == 0) 
            addError("No attached appenders found.");
            return;
        
        if (queueSize < 1) 
            addError("Invalid queue size [" + queueSize + "]");
            return;
        
        // 鍒涘缓涓€涓狝rrayBlockingQueue闃诲闃熷垪锛宷ueueSize榛樿涓?56锛屽垱寤洪樆濉為槦鍒楃殑鍘熷洜鏄細闃叉鐢熶骇鑰呰繃澶氾紝閫犳垚闃熷垪涓厓绱犺繃澶氾紝浜х敓OOM寮傚父
        blockingQueue = new ArrayBlockingQueue<E>(queueSize);
        // 濡傛灉discardingThreshold鏈畾涔夌殑璇濓紝榛樿涓簈ueueSize鐨?/5
        if (discardingThreshold == UNDEFINED)
            discardingThreshold = queueSize / 5;
        addInfo("Setting discardingThreshold to " + discardingThreshold);
        // 灏嗗伐浣滅嚎绋嬭缃负瀹堟姢绾跨▼锛屽嵆褰搄vm鍋滄鏃讹紝鍗充娇闃熷垪涓湁鏈鐞嗙殑鍏冪礌锛屼篃涓嶄細鍦ㄨ繘琛屽鐞?/span>
        worker.setDaemon(true);
        // 涓虹嚎绋嬭缃畁ame渚夸簬璋冭瘯
        worker.setName("AsyncAppender-Worker-" + getName());
        // make sure this instance is marked as "started" before staring the worker Thread
        // 鍚姩绾跨▼
        super.start();
        worker.start();
    

褰撻槦鍒楀凡婊℃椂锛屾槸涓㈠純鑰佺殑鏃ュ織杩樻槸闃诲鏃ュ織鎵撳嵃绾跨▼鐩村埌闃熷垪鏈夌┖浣欏厓绱犳椂锛?nbsp;  杩欎釜闂闇€瑕佸叧娉╝ppend鏂规硶

    @Override
    protected void append(E eventObject) 
        // 鍒ゆ柇闃熷垪涓殑鍏冪礌鏁伴噺鏄惁灏忎簬discardingThreshold锛屽鏋滃皬浜庣殑璇濓紝骞朵笖鏃ュ織绛夌骇灏忎簬info鐨勮瘽锛屽垯鐩存帴涓㈠純杩欎簺鏃ュ織浠诲姟
        if (isQueueBelowDiscardingThreshold() && isDiscardable(eventObject)) 
            return;
        
        preprocess(eventObject);
        // 鏃ュ織鍏ラ槦
        put(eventObject);
    

    private boolean isQueueBelowDiscardingThreshold() 
        return (blockingQueue.remainingCapacity() < discardingThreshold);
    

   // 瀛愮被閲嶅啓鐨勬柟娉?  鍒ゆ柇鏃ュ織绛夌骇
    protected boolean isDiscardable(ILoggingEvent event) 
        Level level = event.getLevel();
        return level.toInt() <= Level.INFO_INT;
    

    private void put(E eventObject) 
        // 鍒ゆ柇鏄惁闃诲锛堥粯璁や负false锛夛紝鍒欎細璋冪敤闃诲闃熷垪鐨刾ut鏂规硶
        if (neverBlock) 
            blockingQueue.offer(eventObject);
         else 
            putUninterruptibly(eventObject);
        
    
    // 鍙腑鏂殑闃诲put鏂规硶
    private void putUninterruptibly(E eventObject) 
        boolean interrupted = false;
        try 
            while (true) 
                try 
                    blockingQueue.put(eventObject);
                    break;
                 catch (InterruptedException e) 
                    interrupted = true;
                
            
         finally 
            if (interrupted) 
                Thread.currentThread().interrupt();
            
        
    

    // ArrayBlockingQueue鐨刾ut鏂规硶锛屽綋count==len鏃讹紝璋冪敤await鏂规硶闃诲绾跨▼
    public void put(E e) throws InterruptedException 
        checkNotNull(e);
        final ReentrantLock lock = this.lock;
        lock.lockInterruptibly();
        try 
            while (count == items.length)
                notFull.await();
            enqueue(e);
         finally 
            lock.unlock();
        
    

addAppender鏂规硶锛屾湁璇ユ柟娉曞彲浠ョ湅鍑猴紝涓€涓紓姝ョ殑appender鍙兘缁戝畾涓€涓悓姝ppender锛岃繖涓猘ppender浼氳鏀惧叆AppenderAttachableImpl鐨刟ppenderList鍒楄〃閲岃竟銆?/p>

    public void addAppender(Appender<E> newAppender) 
        if (appenderCount == 0) 
            appenderCount++;
            addInfo("Attaching appender named [" + newAppender.getName() + "] to AsyncAppender.");
            aai.addAppender(newAppender);
         else 
            addWarn("One and only one appender may be attached to AsyncAppender.");
            addWarn("Ignoring additional appender named [" + newAppender.getName() + "]");
        
    

娉ㄦ剰鍐呴儴绫籛orker鐨剅un鏂规硶锛堟秷璐硅€咃紝灏嗘棩蹇楀啓鍏ョ鐩樼殑绾跨▼鏂规硶锛?/p>

    class Worker extends Thread 

        public void run() 
            AsyncAppenderBase<E> parent = AsyncAppenderBase.this;
            AppenderAttachableImpl<E> aai = parent.aai;

            // loop while the parent is started 涓€鐩村惊鐜煡閬撶嚎绋嬭涓柇
            while (parent.isStarted()) 
                try // 浠庨樆濉為槦鍒椾腑鑾峰彇鍏冪礌锛屼氦鐢辩粰鍚屾鐨刟ppender灏嗘棩蹇楁墦鍗板埌纾佺洏
                    E e = parent.blockingQueue.take();
                    aai.appendLoopOnAppenders(e);
                 catch (InterruptedException ie) 
                    break;
                
            

            addInfo("Worker thread will flush remaining events before exiting. ");
            //鎵ц鍒拌繖閲岃鏄庤绾跨▼琚腑鏂紝鍒欐妸闃熷垪閲岃竟鐨勫墿浣欐棩蹇椾换鍔″埛鏂板埌纾佺洏
            for (E e : parent.blockingQueue) 
                aai.appendLoopOnAppenders(e);
                parent.blockingQueue.remove(e);
            

            aai.detachAndStopAllAppenders();
        
    

 

11.2Tomcat鐨凬ioEndPoint涓殑ConcurrentLinkedQueue

銆€銆€Tomcat鐨勫鍣ㄧ粨鏋勶細

銆€銆€鎶€鏈浘鐗? src=

銆€銆€鍏朵腑Connector鏄竴涓ˉ姊侊紝浠栨妸server鍜孍ngine杩炴帴璧锋潵浜嗭紝Connector鐨勪綔鐢ㄦ槸鎺ュ彈瀹㈡埛绔姹傦紝鐒跺悗鎶婅姹傚鎵樼粰Engine銆傚湪Connector涓娇鐢‥ndpoint鏉ヨ繘琛屽鐞嗘牴鎹笉鍚岀殑澶勭悊鏂瑰紡鍙垎涓篘ioEndpoint銆丣IoEndpoint銆丄prEndpoint銆?/p>

銆€NioEndpoint涓笁澶х粍浠剁殑鍏崇郴锛?/p>

銆€銆€鎶€鏈浘鐗? src=

銆€銆€Acceptor浣滅敤锛氭槸濂楁帴瀛楃殑鎺ュ彈绾跨▼锛岀敤鏉ユ帴鍙楃敤鎴风殑璇锋眰锛屽苟鎶婅姹傚皝瑁呰繘Poller鐨勯槦鍒楋紝涓€涓狢onnector涓彧鏈変竴涓狝cceptor銆?/p>

銆€銆€Poller鍋剁敤锛氭槸濂楁帴瀛楃殑澶勭悊绾跨▼锛屾瘡涓€涓狿oller鍐呴儴閮芥湁涓€涓嫭鏈夌殑闃熷垪锛孭oller绾跨▼鍒欎粠鑷繁鐨勯槦鍒楅噷杈硅幏鍙栧叿浣撶殑浜嬩欢浠诲姟锛岀劧鍚庡皢鍏朵氦缁橶orker杩涜澶勭悊锛屽叾涓璓oller鐨勭嚎绋嬫暟鍜宑pu涓暟鏈夊叧銆?/p>

銆€銆€Worker锛氭槸鏃堕棿澶勭悊璇锋眰鐨勭嚎绋嬶紝Worker鍙槸缁勪欢鐨勫悕瀛楋紝鐪熸鍋氫簨鎯呯殑鏄疭ocketProcessor銆?/p>

銆€銆€鐢辨鍙锛宼omcat浣跨敤闃熷垪灏嗘帴鍙楄姹傚拰澶勭悊璇锋眰鎿嶄綔杩涜瑙h€︼紝瀹炵幇寮傛澶勭悊銆?/p>

銆€銆€鍏跺疄Tomcat涓璄ndpoint涓殑姣忎竴涓狿oller閲岃竟閮界淮鎶ょ潃涓€涓狢oncurrentLinkedQueue闃熷垪锛岀敤鏉ョ紦瀛樿姹備换鍔★紝鍏舵湰韬篃鏄竴涓鐢熶骇鑰?鍗曟秷璐硅€呮ā鍨嬨€?/p>

銆€銆€1銆丄cceptor鐢熶骇鑰?/p>

銆€銆€Acceptor绾跨▼鐨勪綔鐢細鎺ュ彈瀹㈡埛绔姹傚苟灏嗗叾鏀惧叆Poller涓殑闃熷垪銆?/p>

銆€銆€鏃跺簭鍥撅紙绠€鍗曪級锛?/p>

銆€銆€鎶€鏈浘鐗? src=

 

 11.7鍒涘缓绾跨▼鍜岀嚎绋嬫睜鏃惰鎸囧畾涓庝笟鍔$浉鍏崇殑鍚嶇О

銆€銆€鍦ㄦ棩甯稿紑鍙戣繃绋嬩腑锛屽綋鍦ㄤ竴涓簲鐢ㄤ腑闇€瑕佸垱寤哄涓嚎绋嬫垨鑰呯嚎绋嬫睜鏃讹紝鏈€濂界粰姣忎釜绾跨▼鎴栬€呮瘡涓嚎绋嬫睜鏍规嵁涓氬姟绫诲瀷璁剧疆鍏蜂綋鐨勫悕绉帮紝浠ヤ究鍦ㄥ嚭鐜伴棶棰樻椂鏂逛究瀹氫綅銆?/p>

銆€銆€1銆佸垱寤哄涓嚎绋嬫渚?/p>

package com.nxz.blog.otherTest;

public class TestThread0014 


    public static void main(String[] args) 

        // 鍋囪璇ョ嚎绋嬫搷浣滀繚鍗曟ā鍧?/span>
        Thread t1 = new Thread(new Runnable() 
            @Override
            public void run() 
                System.out.println("鎿嶄綔淇濆崟");
                try 
                    Thread.sleep(500);
                 catch (InterruptedException e) 
                    e.printStackTrace();
                
                // 鎵嬪姩鎶涘紓甯?/span>
                throw new NullPointerException();
            
        );

        // 鍋囪璇ユā鍧楁槸鎶曚繚妯″潡
        Thread t2 = new Thread(new Runnable() 
            @Override
            public void run() 
                System.out.println("鎿嶄綔鎶曚繚");
            
        );


        t1.start();
        t2.start();
    

 銆€銆€浠ヤ笂浠g爜鎵ц缁撴灉锛?浠庡紓甯镐俊鎭腑鍙兘鐪嬪嚭鏄疶hread-0鍑虹幇闂浜嗭紝涓嶈兘纭畾鍏蜂綋鏄摢涓€涓ā鍧楀嚭鐨勯棶棰橈紝纭闂鍥伴毦

鎿嶄綔淇濆崟
鎿嶄綔鎶曚繚
Exception in thread "Thread-0" java.lang.NullPointerException
    at com.nxz.blog.otherTest.TestThread0014$1.run(TestThread0014.java:18)
    at java.lang.Thread.run(Thread.java:748)

鐪婽hread鏋勯€犲嚱鏁帮細

    public Thread(Runnable target) 
        // 褰撳弬鏁颁腑娌℃湁鎻愪緵name鏃讹紝榛樿浣跨敤nextThreadNum鐢熸垚缂栧彿鏉ュ綋鍋氱嚎绋媙ame
        init(null, target, "Thread-" + nextThreadNum(), 0);
    

淇敼浠ヤ笂浠g爜锛氬嵆灏嗗垱寤虹嚎绋嬫椂浣跨敤澶氫釜鍙傛暟鐨勬瀯閫犲嚱鏁帮細

    public static void main(String[] args) 

        // 鍋囪璇ョ嚎绋嬫搷浣滀繚鍗曟ā鍧?/span>
        Thread t1 = new Thread(new Runnable() 
            @Override
            public void run() 
                System.out.println("鎿嶄綔淇濆崟");
                try 
                    Thread.sleep(500);
                 catch (InterruptedException e) 
                    e.printStackTrace();
                
                // 鎵嬪姩鎶涘紓甯?/span>
                throw new NullPointerException();
            
        , "淇濆崟妯″潡");

        // 鍋囪璇ユā鍧楁槸鎶曚繚妯″潡
        Thread t2 = new Thread(new Runnable() 
            @Override
            public void run() 
                System.out.println("鎿嶄綔鎶曚繚");
            
        , "鎶曚繚妯″潡");


        t1.start();
        t2.start();
    

銆€銆€鎵ц缁撴灉锛?寰堟槑鏄剧殑鐪嬪嚭鏄繚鍗曟ā鍧椾骇鐢熶簡闂

鎿嶄綔淇濆崟
鎿嶄綔鎶曚繚
Exception in thread "淇濆崟妯″潡" java.lang.NullPointerException
    at com.nxz.blog.otherTest.TestThread0014$1.run(TestThread0014.java:19)
    at java.lang.Thread.run(Thread.java:748)

銆€銆€2銆佸垱寤虹嚎绋嬫睜鏃朵篃瑕佹寚瀹氱嚎绋嬫睜鐨勫悕绉?/p>

銆€銆€鐢辩嚎绋嬫睜鐨勬瀯閫犲嚱鏁帮紝鍙互鐪嬪嚭锛岄粯璁ょ殑鍚嶇О鏄被浼?ldquo;pool-1-thread-1”杩欐牱鐨勫悕绉?/p>

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              RejectedExecutionHandler handler) 
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), handler);
    
    public static ThreadFactory defaultThreadFactory() 
        return new DefaultThreadFactory();
    
        DefaultThreadFactory() 
            SecurityManager s = System.getSecurityManager();
            group = (s != null) ? s.getThreadGroup() :
                                  Thread.currentThread().getThreadGroup();
            namePrefix = "pool-" +
                          poolNumber.getAndIncrement() +
                         "-thread-";
        

鍥犳浣跨敤ThreadPoolExecutor鏋勫缓绾跨▼姹犵殑鏃跺€欒嚜瀹氫箟ThreadFactory鐨勫悕绉帮紙鍗充豢鐓efaultThreadFactory浠跨収涓€涓狢ustomerThreadFactory锛屽彧闇€淇敼namePrefix鍗冲彲锛夛細

package com.nxz.blog.otherTest;


import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

public class TestThread0015 


    static class NamedThreadFactory implements ThreadFactory 
        private static final AtomicInteger poolNumber = new AtomicInteger();
        private final ThreadGroup group;
        private final AtomicInteger threadNumber = new AtomicInteger();
        private final String namePrefix;

        public NamedThreadFactory(String name) 
            SecurityManager s = System.getSecurityManager();
            group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
            if (name == null || name.isEmpty()) 
                name = "pool";
            
            namePrefix = name + "-" + poolNumber.getAndIncrement() + "-thread-";
        

        @Override
        public Thread newThread(Runnable r) 
            // 缁欑嚎绋嬩篃璁剧疆鍚嶇О
            Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0);
            if (t.isDaemon()) 
                t.setDaemon(false);
            
            if (t.getPriority() != Thread.NORM_PRIORITY) 
                t.setPriority(Thread.NORM_PRIORITY);
            
            return t;
        
    


    static ExecutorService executorServicePolicy = new ThreadPoolExecutor(5, 5, 1, TimeUnit.MINUTES,
            new LinkedBlockingQueue<>(), new NamedThreadFactory("淇濆崟妯″潡"));

    static ExecutorService executorServiceProposal = new ThreadPoolExecutor(5, 5, 1, TimeUnit.MINUTES,
            new LinkedBlockingQueue<>(), new NamedThreadFactory("鎶曚繚妯″潡"));

    public static void main(String[] args) 
        executorServicePolicy.execute(new Runnable() 
            @Override
            public void run() 
                System.out.println("aaaa");
                throw new NullPointerException();
            
        );
        executorServiceProposal.execute(new Runnable() 
            @Override
            public void run() 
                System.out.println("bbbb");
//                throw new NullPointerException();
            
        );

        executorServicePolicy.shutdown();
        executorServiceProposal.shutdown();
    

銆€銆€浠ヤ笂浠g爜鎵ц缁撴灉锛氬彲浠ユ槑鏄剧湅鍑烘槸淇濆崟妯″潡绾跨▼姹犳姤閿欎簡

aaaa
Exception in thread "淇濆崟妯″潡-0-thread-0" java.lang.NullPointerException
bbbb
    at com.nxz.blog.otherTest.TestThread0015$1.run(TestThread0015.java:51)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

 

11.8浣跨敤绾跨▼姹犵殑鎯呭喌涓嬪綋绋嬪簭缁撴潫鐨勬椂鍊欒寰楄皟鐢╯hutdown鏂规硶鍏抽棴绾跨▼姹?/p>

銆€銆€鍦ㄦ棩甯稿紑鍙戣繃绋嬩腑锛屼负浜嗗鐢ㄧ嚎绋嬶紝缁忓父浼氱敤鍒扮嚎绋嬫睜锛岀劧鑰屼娇鐢ㄥ畬绾跨▼姹犲悗濡傛灉涓嶈皟鐢╯hutdown鏂规硶鍏抽棴绾跨▼姹狅紝鍒欎細瀵艰嚧绾跨▼姹犺祫婧愬緱涓嶅埌閲婃斁銆?/p>

銆€銆€1銆侀棶棰樺鐜?/p>

package com.nxz.blog.otherTest;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TestThread0013 

    static void executeOne() 
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        executorService.execute(new Runnable() 
            @Override
            public void run() 
                System.out.println("execute One");
            
        );
//executorService.shutdoan()锛?
static void executeTwo() ExecutorService executorService = Executors.newSingleThreadExecutor(); executorService.execute(new Runnable() @Override public void run() System.out.println("execute Two"); );
//executorService.shutdoan();
public static void main(String[] args) System.out.println("main start"); executeOne(); executeTwo(); System.out.println("end");

鎵ц浠g爜锛氬綋鍓嶄富绾跨▼骞舵病鏈夌粨鏉燂紝鍗宠祫婧愭病鏈夐噴鏀撅紱 濡傛灉灏嗘敞閲婃斁寮€鐨勮瘽锛屽垯涓荤嚎绋嬩細缁撴潫

鎶€鏈浘鐗? src=  ----- 銆嬨€?img alt="鎶€鏈浘鐗? src="http://image.mamicode.com/info/201908/20190818174637880900.png" />

閭d负浠€涔堜笉鎵цshutdown鏃讹紝涓嶉噴鏀捐祫婧愶紵

銆€銆€鍦ㄥ熀纭€绡囷紝鏇剧粡璇磋繃瀹堟姢绾跨▼鍜岀敤鎴风幇鍦猴紝jvm閫€鍑虹殑鏉′欢鏄綋鍓嶄笉瀛樺湪鐢ㄦ埛绾跨▼锛岃€岀嚎绋嬫睜榛樿鍒涘缓鐨勭嚎绋嬮兘鏄敤鎴风嚎绋嬶紝鑰岀嚎绋嬫睜涓殑绾跨▼浼氫竴鐩村瓨鍦紝鎵€鏈塲vm浼氫竴鐩磋繍琛屻€?/p>

 

11.9浣跨敤FutureTask鏃堕渶瑕佹敞鎰忕殑浜嬫儏

 銆€銆€绾跨▼姹犱娇鐢‵utureTask鏃跺鏋滄妸鎷掔粷绛栫暐璁剧疆涓篋iscardPolicy鎴栬€匘iscardOldestPolicy锛屽苟涓斿湪琚嫆缁濅换鍔$殑Future瀵硅薄涓婅皟鐢ㄤ簡鏃犲弬鐨刧et鏂规硶锛岄偅涔堣皟鐢ㄧ嚎绋嬩細涓€鐩撮樆濉炪€?/p>

銆€銆€1銆侀棶棰樺鐜?/p>

package com.nxz.blog.otherTest;

import java.util.concurrent.*;

public class TestThread0012 

    private final static ThreadPoolExecutor executorService = new ThreadPoolExecutor(1, 1, 1L, TimeUnit.MINUTES,
            new ArrayBlockingQueue<Runnable>(1), new ThreadPoolExecutor.DiscardPolicy());

    public static void main(String[] args) throws ExecutionException, InterruptedException 
        Future<?> futureOne = executorService.submit(new Runnable() 
            @Override
            public void run() 
                System.out.println("start runnable one");
                try 
                    Thread.sleep(5000);
                 catch (InterruptedException e) 
                    e.printStackTrace();
                
            
        );

        Future<?> futureTwo = executorService.submit(new Runnable() 
            @Override
            public void run() 
                System.out.println("start runnable two");
            
        );

        Future futureThree = null;
        try 
            futureThree = executorService.submit(new Runnable() 
                @Override
                public void run() 
                    System.out.println("start runnable three");
                
            );
         catch (Exception e) 
            System.out.println(e.getLocalizedMessage());
        

        System.out.println("futureOne" + futureOne.get());
        System.out.println("futureTwo" + futureTwo.get());
        // 浠g爜鎵ц鍒拌浣嶇疆鍚庝笉鍚戜笅鎵ц浜嗭紝涔熷氨鏄痜utureThree.get鏂规硶闃诲浜?/span>
        System.out.println("futureThree" + futureThree.get());
        System.out.println("end");

        executorService.shutdown();
    

銆€銆€閭d箞涓轰粈涔坒utureThree.get鏂规硶闃诲锛岄渶瑕佺湅FutureTask涓殑get鏂规硶鏄€庢牱瀹炵幇鐨勶紙浠€涔堟儏鍐典笅浼氳繑鍥炲€硷紝浠€涔堟儏鍐典笅浼氶樆濉烇級锛?/p>

銆€銆€銆€銆€鍏堝垎鏋愪笂杈逛唬鐮佺殑娴佺▼锛岀嚎绋嬫睜鐨勫ぇ灏忎负1锛屾湁鐣岄槦鍒椾篃鏄?锛屼篃灏辨槸璇达紝褰撻樆濉為槦鍒椾腑宸茬粡鏈変竴涓换鍔℃椂锛屽湪submit浠诲姟鏃讹紝灏变細鎵ц鎷掔粷绛栫暐锛屼笂杈逛唬鐮乫utureOne鐨勪换鍔¢噷杈规湁涓潯鐪狅紙璇ヤ綔鐢ㄥ氨鏄娇futureTwo杩涘叆闃诲闃熷垪锛宖utureThree涓殑浠诲姟鎵ц鎷掔粷绛栫暐锛夛紝閭d箞鐪嬩笅submit鐨勪唬鐮佹祦绋嬪共浜嗕粈涔堬細

    // 鎻愪氦浠诲姟鏃讹紝浼氱幇灏唕unnable灏佽涓轰竴涓狥uture瀵硅薄
    public Future<?> submit(Runnable task) 
        if (task == null) throw new NullPointerException();
        RunnableFuture<Void> ftask = newTaskFor(task, null);
        execute(ftask);
        return ftask;
    
   // newTaskFor鏂规硶锛岀洿鎺ュ垱寤轰簡涓€涓狥utureTask瀵硅薄锛岃€孎utureTask瀵硅薄鐨勯粯璁ょ姸鎬佹槸NEW
    protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) 
        return new FutureTask<T>(runnable, value);
    

    public FutureTask(Runnable runnable, V result) 
        this.callable = Executors.callable(runnable, result);
        this.state = NEW;       // ensure visibility of callable
    

銆€銆€浠庝笂杈逛唬鐮佸彲浠ョ湅鍑簊ubmit鏂规硶浼氬皢浠诲姟灏佽鎴愪竴涓狥utureTask瀵硅薄锛岃€岃瀵硅薄榛樿鐨勭姸鎬佹槸NEW锛岄偅涔堢户缁湅execute鏂规硶锛堝湪璇ユ柟娉曢噷杈逛細鏍规嵁褰撳墠浠诲姟鐨勪釜鏁版潵鍒ゆ柇鏄惁鎵ц闃诲闃熷垪锛夛細

    public void execute(Runnable command) 
        if (command == null)
            throw new NullPointerException();
        int c = ctl.get();
        if (workerCountOf(c) < corePoolSize) 
            if (addWorker(command, true))
                return;
            c = ctl.get();
        
        if (isRunning(c) && workQueue.offer(command)) 
            int recheck = ctl.get();
            if (! isRunning(recheck) && remove(command))
                reject(command);
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        
        else if (!addWorker(command, false))
            // 鎵ц鎷掔粷绛栫暐
            reject(command);
    
    // 鍥犱负鍒涘缓绾跨▼姹犳椂锛岄厤缃殑鏄疍IscardPolicy锛屽洜姝ょ湅璇ュ璞′腑reject鏂规硶鎵ц浜嗕粈涔堟搷浣?/span>
    final void reject(Runnable command) 
        handler.rejectedExecution(command, this);
    

    public static class DiscardPolicy implements RejectedExecutionHandler 
  
        public DiscardPolicy()  
      // 鍙互鐪嬪埌rejfect浠€涔堜篃娌℃湁鎵ц
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) 
        
    

銆€銆€浠庝笂杈逛唬鐮佸彲浠ョ湅鍑猴紝褰撴墽琛屾嫆缁濈瓥鐣ユ椂锛屼粈涔堥兘娌℃湁鎵ц锛屼篃灏辨槸璇存病鏈夊褰撳墠浠诲姟鍋氫换浣曟搷浣溿€傦紙鑰屼笅杈硅繖涓猣uture鐨刧et鏂规硶锛岃兘澶熻繑鍥炲€肩殑鏃跺€欙紝futureTask鐨勭姸鎬佸繀椤诲ぇ浜嶤OMPLETING锛岃繖鍜屼笂杈硅鐨勪笉绗﹀悎锛屽洜姝わ紝褰揻utureThree.get鏃讹紝浼氶樆濉烇紙褰撴嫆缁濈瓥鐣ヨ缃负DIscardOldestPolicy鏃讹紝鍚屾牱鏈夎闂锛夛級

銆€銆€浠庝笅杈笷utureTask涓殑get鏂规硶鍙互鐪嬪嚭锛屽綋Future鐨勭姸鎬侊紙future鏄湁鐘舵€佺殑锛夊€硷紝灏忎簬COMPLETING鏃讹紝灏变細闃诲锛屽ぇ浜庣殑璇濆氨浼氳繑鍥炰竴涓€?/p>

    public V get() throws InterruptedException, ExecutionException 
        int s = state;
        if (s <= COMPLETING)
            s = awaitDone(false, 0L);
        return report(s);
    
    private volatile int state;
    private static final int NEW          = 0;
    private static final int COMPLETING   = 1;
    private static final int NORMAL       = 2;
    private static final int EXCEPTIONAL  = 3;
    private static final int CANCELLED    = 4;
    private static final int INTERRUPTING = 5;
    private static final int INTERRUPTED  = 6;

銆€銆€瑙e喅闃诲鐨勬柟娉曪細1銆佸彲浠ュ皢鎷掔粷绛栫暐璁剧疆涓洪粯璁わ紙AbortPolicy锛?銆佸敖閲忎娇鐢ㄥ甫瓒呮椂鏃堕棿鐨刧et鏂规硶锛岃繖鏍峰嵆浣夸細闃诲锛屼篃浼氬洜涓鸿秴鏃惰€岃繑鍥?/span>銆?銆佽嚜瀹氫箟鎷掔粷绛栫暐锛岄噸鍐檙ejectedExecution鏂规硶锛屽皢futureTask鐨勭姸鎬佽缃负澶т簬COMPLETING鍗冲彲銆?/p>

 

 

 11.10ThreadLocal浣跨敤涓嶅綋瀵艰嚧鐨勫唴瀛樻硠婕?/p>

銆€銆€鍐呭瓨娉勬紡Memory leak锛氭槸鎸囩▼搴忎腑宸茬粡鍔ㄦ€佸垎閰嶇殑鍫嗗唴瀛橈紝鐢变簬鏌愮鍘熷洜绋嬪簭鏈噴鏀炬垨鏃犳硶閲婃斁锛岄€犳垚绯荤粺鍐呭瓨娴垂锛屽鑷寸▼搴忚繍琛岄€熷害鍑忔參锛岀敋鑷崇▼搴忓穿婧冪瓑鍚庢灉銆?/p>

銆€銆€鍦ㄥ熀纭€绡囨湁浠嬬粛锛孴hreadLocal鍙槸涓€涓伐鍏风被锛屽叿浣撳瓨鏀惧彉閲忔椂绾跨▼鐨則hreadlocals鍙橀噺銆傝鍙橀噺鏄疶hreadLocalMap绫诲瀷鐨勫彉閲忥紝濡備笅鍥撅細

銆€銆€鎶€鏈浘鐗? src=

銆€銆€鐢卞浘鍙煡锛孴hreadLocalMap鍐呴儴鏄竴涓狤ntry鏁扮粍锛孍ntry缁ф壙鑷猈eakReference锛孍ntry鍐呴儴鐨剉alue鐢ㄦ潵瀛樻斁ThreadLocal鐨剆et鏂规硶浼犻€掔殑姹狅紝key鍒欐槸ThreadLocal瀵硅薄寮曠敤銆?/p>

銆€銆€Entry鏋勯€狅細

銆€銆€key浼犻€掔粰WeakReference鏋勯€狅紝涔熷氨鏄ThreadLocalMap閲岃竟鐨刱ey涓篢hreadLocal鐨勫急寮曠敤锛屽叿浣撳氨鏄痳eferent鍙橀噺寮曠敤浜員hreadLocal瀵硅薄锛寁alue涓哄叿浣撹皟鐢═hreadLocal鐨剆et鏂规硶鏃朵紶閫掔殑鍊?/p>

Entry(ThreadLocal<?> k, Object v) 
                super(k);
                value = v;
    
    public WeakReference(T referent) 
        super(referent);
    
    Reference(T referent) 
        this(referent, null);
    

    Reference(T referent, ReferenceQueue<? super T> queue) 
        this.referent = referent;
        this.queue = (queue == null) ? ReferenceQueue.NULL : queue;
    

銆€銆€褰撲竴涓嚎绋嬭皟鐢═hreadLocal鐨剆et鏂规硶璁剧疆鍙橀噺鏃讹紝褰撳墠绾跨▼鐨凾hreadLocalMap閲岃竟浼氬瓨鏀句竴涓褰曪紝杩欎釜璁板綍鐨刱ey涓篢hreadLocal鐨勫急寮曠敤锛寁alue涓鸿缃殑鍊笺€傚鏋滅嚎绋嬩竴鐩存病鏈夎皟鐢╮emove鏂规硶锛屽苟涓旇繖涓椂鍊欏叾浠栧湴鏂硅繕鏈夊ThreadLocal鐨勫紩鐢紝鍒欏綋鍓嶇嚎绋嬬殑ThreadLocalMap鍙橀噺閲岃竟瀛樺湪瀵筎hreadLocal鍙橀噺鐨勫紩鐢ㄥ拰瀵箆alue瀵硅薄鐨勫簲鐢紝浠栦滑鏄笉浼氳閲婃斁鐨勶紝杩欏氨浼氶€犳垚鍐呭瓨娉勬紡銆傚彟澶栵紝鍗充娇杩欎釜ThreadLocal鍙橀噺娌℃湁鍏朵粬寮轰緷璧栵紝鑰屽綋鍓嶇嚎绋嬭繕瀛樺湪鐨勶紝鐢变簬绾跨▼鐨凾hreadLocalMap閲岃竟鐨刱ey鏄急寮曠敤锛屾墍浠ュ綋鍓嶇嚎绋嬬殑ThreadLocal鍙橀噺鐨勫急寮曠敤浼氬湪GC鐨勬椂鍊欏洖鏀讹紝浣嗘槸瀵瑰簲鐨剉alue涓嶄細鍥炴敹锛岃繕鏄細閫犳垚鍐呭瓨娉勬紡銆?/p>

銆€銆€铏界劧ThreadLocalMap鎻愪緵鐨剆et銆乬et銆乺emove鏂规硶鎻愪緵浜嗗湪涓€浜涙椂鏈轰笅瀵筫ntry杩涜娓呯悊锛屼絾杩欐槸涓嶅強鏃剁殑锛屼篃涓嶆槸姣忔鎵ц鐨勶紝鎵€浠ュ湪涓€浜涙儏鍐典笅杩樻槸浼氭湁鍐呭瓨娉勬紡銆?/p>

銆€銆€瑙e喅鍐匱hreadLocal鍐呭瓨娉勬紡鐨勬柟娉?/strong>锛氬湪ThreadLocal浣跨敤瀹屾瘯鍚庯紝鍙婃椂璋冪敤remove鏂规硶杩涜娓呯悊宸ヤ綔銆?/p>

銆€銆€妗堜緥锛氬湪绾跨▼姹犱腑浣跨敤ThreadLocal瀵艰嚧鍐呭瓨娉勬紡

package com.nxz.blog.otherTest;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class TestThread0010 


    static class LocalVariable 
        //鐢宠涓€鍧楀浐瀹氬ぇ灏忕殑鍐呭瓨
        private Long[] a = new Long[1024 * 1024];
    
    
    static ThreadLocal<LocalVariable> localVariable = new ThreadLocal<>();
    // 鏍稿績绾跨▼鏁板拰鏈€澶х嚎绋嬫暟閮戒负5锛岃秴鏃舵椂闂?鍒嗛挓
    final static ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(5, 5, 1, TimeUnit.MINUTES,new LinkedBlockingQueue<>());

    public static void main(String[] args) throws InterruptedException 
        // 50涓嚎绋嬶紝姣忎釜绾跨▼閮藉線ThreadLocal涓斁鍏ヤ竴涓浐瀹氬ぇ灏忕殑瀵硅薄
        for (int i = 0; i < 50; i++) 
            poolExecutor.execute(new Runnable() 
                @Override
                public void run() 
                    localVariable.set(new LocalVariable());
                    System.out.println("user LocalVariable");
                    Thread thread1 = Thread.currentThread();
                    //localVariable.remove();

                

            );
            Thread thread = Thread.currentThread();
            Thread.sleep(1000);
        
        System.out.println("pool executor over");
銆€銆€銆€銆€銆€//poolExecutor.shutdown();

杩愯浠g爜锛屼娇鐢╦concle鐩戞帶鍐呭瓨鍙樺寲锛堟垜鑷繁椤垫祴璇曟潵锛屼絾鏄樉绀烘晥鏋滄病鏈変功涓婄殑鍥惧ソ锛夛細

鎶€鏈浘鐗? src=

绗簩娆¤繍琛屾椂锛屾斁寮€remove鏂规硶鐨勬敞閲婏紝缁х画鐪嬪唴瀛樺彉鍖栵細

鎶€鏈浘鐗? src=

鐢变袱娆¤繍琛岀殑鍐呭瓨鍙樺寲锛屽彲浠ョ湅鍑猴紝绗竴娆¤繍琛屾椂锛屽綋50涓嚎绋嬭繍琛屽畬姣曞悗锛堟鏃朵富绾跨▼骞舵病鏈夌粨鏉燂紝鍥犱负娌℃湁璋冪敤shutdown鏂规硶锛夛紝缁撴潫鏃剁殑鍐呭瓨涓?5MB宸﹀彸锛岀浜屾杩愯鏃讹紝缁撴潫鍐呭瓨涓?5MB宸﹀彸锛岀敱姝ゅ彲浠ユ槑鏄剧殑鐪嬪嚭锛屽綋娌℃湁璋冪敤remove鏂规硶鏄細閫犳垚鍐呭瓨娉勬紡銆傦紙PS锛氬皻鏈悊瑙g殑闂锛氳繖閲屼负鍟ヤ袱娆″樊璺?0MB锛岃繖涓€兼槸鎬庝箞鍑烘潵鐨勶紝杩樻槸娌$悊椤猴紵锛焠ew LocalVariable瀵硅薄澶ф鍗犵敤1MB鍐呭瓨锛岀浉宸?0MB锛岀浉褰撲簬姣忎竴涓猂unnable浠诲姟锛岄兘娌℃湁缁忚繃鍥炴敹锛屼粛鐒朵繚鐣欏湪鍐呭瓨涓€傝繕鏈夊氨鏄嚎绋嬫睜涓湁5涓嚎绋嬪惊鐜埄鐢紝閭d箞涔熷氨琛ㄧず鎬诲叡鏈?涓猅hreadLocalMap瀵硅薄锛岃€孴hreadLocalMap鐨刱ey涓哄綋鍓嶇嚎绋嬶紝閭d釜set鏂规硶鐨勬椂鍊欙紝鍚庡簭鐨剆et鐨剉alue娌℃湁瑕嗙洊涔嬪墠鐨勫悧锛熷鏋滆鐩栫殑璇濓紝閭d箞鏈€缁堜袱娆¤繍琛屽簲璇ョ浉宸?MB锛屾垨鑰呮槸缁忚繃涓€涓洖鏀跺急寮曠敤锛岄偅涔堜篃鏄?0MB锛?0MB鏄€庢牱鍑烘潵鐨勶紵锛燂級

鍘熷洜锛?/p>

銆€銆€绗竴娆¤繍琛屼唬鐮佺殑鏃跺€欙紝娌℃湁璋冪敤remove鏂规硶锛岃繖灏卞鑷翠簡褰?涓牳蹇冪嚎绋嬭繍琛屽畬姣曞悗锛岀嚎绋嬬殑threadlocals閲岃竟鐨刵ew LocalVariable锛堬級瀵硅薄骞舵病鏈夐噴鏀俱€傝櫧鐒剁嚎绋嬫墽琛屽畬姣曚簡锛屼絾鏄?涓牳蹇冪嚎绋嬩細涓€鐩村瓨鍦紝鐭ラ亾琚獼VM鏉€姝汇€傦紙杩欓噷闇€瑕佹敞鎰忕殑鏄細localVariable琚畾涔変负static鍙橀噺锛岃櫧鐒跺湪绾跨▼鐨凾hreadLocalMap閲岃竟瀵筶ocalVariable杩涜浜嗗急寮曠敤锛屼絾鏄痩ocalVariable骞朵笉浼氳鍥炴敹锛夛紝娌℃湁琚洖鏀舵槸鍥犱负瀛樺湪寮哄紩鐢細thread--銆媡hreadLocalMap--銆媏ntry--銆媣alue

銆€銆€绗簩娆★紝鐢变簬鍙婃椂鐨勮皟鐢ㄤ簡remove鏂规硶锛屾墍浠ヤ笉浼氶€犳垚鍐呭瓨娉勬紡銆?nbsp;

 

以上是关于java骞跺彂缂栫▼涔嬬編-闃呰璁板綍11的主要内容,如果未能解决你的问题,请参考以下文章

銆愬師鍒涖€慗ava骞跺彂缂栫▼绯诲垪30 | ThreadLocal

Java澶氱嚎绋嬪涔犳€荤粨涔?--澶氱嚎绋嬪熀纭€

Java 骞跺彂锛氬唴缃攣 Synchronized

骞跺彂鐩稿叧闂浠ュ強java鍩虹鐭ヨ瘑

[leetcode] 棰樿В璁板綍 11-20

JAVA鍏ラ棬濉潙璁板綍