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>
銆€銆€銆€銆€ ----- 銆嬨€嬨€?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>
銆€銆€
銆€銆€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鐨勫鍣ㄧ粨鏋勶細
銆€銆€
銆€銆€鍏朵腑Connector鏄竴涓ˉ姊侊紝浠栨妸server鍜孍ngine杩炴帴璧锋潵浜嗭紝Connector鐨勪綔鐢ㄦ槸鎺ュ彈瀹㈡埛绔姹傦紝鐒跺悗鎶婅姹傚鎵樼粰Engine銆傚湪Connector涓娇鐢‥ndpoint鏉ヨ繘琛屽鐞嗘牴鎹笉鍚岀殑澶勭悊鏂瑰紡鍙垎涓篘ioEndpoint銆丣IoEndpoint銆丄prEndpoint銆?/p>
銆€NioEndpoint涓笁澶х粍浠剁殑鍏崇郴锛?/p>
銆€銆€
銆€銆€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>
銆€銆€
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爜锛氬綋鍓嶄富绾跨▼骞舵病鏈夌粨鏉燂紝鍗宠祫婧愭病鏈夐噴鏀撅紱 濡傛灉灏嗘敞閲婃斁寮€鐨勮瘽锛屽垯涓荤嚎绋嬩細缁撴潫
----- 銆嬨€?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>
- 銆€銆€鏈夊叧鍐呭瓨娉勬紡鐨勫崥瀹細https://blog.csdn.net/xlgen157387/article/details/78298840
銆€銆€鍦ㄥ熀纭€绡囨湁浠嬬粛锛孴hreadLocal鍙槸涓€涓伐鍏风被锛屽叿浣撳瓨鏀惧彉閲忔椂绾跨▼鐨則hreadlocals鍙橀噺銆傝鍙橀噺鏄疶hreadLocalMap绫诲瀷鐨勫彉閲忥紝濡備笅鍥撅細
銆€銆€
銆€銆€鐢卞浘鍙煡锛孴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瀵艰嚧鍐呭瓨娉勬紡 杩愯浠g爜锛屼娇鐢╦concle鐩戞帶鍐呭瓨鍙樺寲锛堟垜鑷繁椤垫祴璇曟潵锛屼絾鏄樉绀烘晥鏋滄病鏈変功涓婄殑鍥惧ソ锛夛細 绗簩娆¤繍琛屾椂锛屾斁寮€remove鏂规硶鐨勬敞閲婏紝缁х画鐪嬪唴瀛樺彉鍖栵細 鐢变袱娆¤繍琛岀殑鍐呭瓨鍙樺寲锛屽彲浠ョ湅鍑猴紝绗竴娆¤繍琛屾椂锛屽綋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的主要内容,如果未能解决你的问题,请参考以下文章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();