Java編程中靜態(tài)內(nèi)部類與同步類的寫法示例
java靜態(tài)內(nèi)部類
將某個(gè)內(nèi)部類定義為靜態(tài)類,跟將其他類定義為靜態(tài)類的方法基本相同,引用規(guī)則也基本一致。不過其細(xì)節(jié)方面仍然有很大的不同。具體來說,主要有如下幾個(gè)地方要引起各位程序開發(fā)人員的注意。
(一)一般情況下,如果一個(gè)內(nèi)部類不是被定義成靜態(tài)內(nèi)部類,那么在定義成員變量或者成員方法的時(shí)候,是不能夠被定義成靜態(tài)成員變量與靜態(tài)成員方法的。也就是說,在非靜態(tài)內(nèi)部類中不可以聲明靜態(tài)成員。
(二)一般非靜態(tài)外部類可以隨意訪問其外部類的成員變量以及方法(包括聲明為private的方法),但是如果一個(gè)內(nèi)部類被聲明為static,則其在訪問包括自身的外部類會(huì)有諸多的限制。靜態(tài)內(nèi)部類不能訪問其外部類的非靜態(tài)成員變量和方法。
(三)在一個(gè)類中創(chuàng)建非靜態(tài)成員內(nèi)部類的時(shí)候,有一個(gè)強(qiáng)制性的規(guī)定,即內(nèi)部類的實(shí)例一定要綁定在外部類的實(shí)例中。然后要在一個(gè)外部類中定義一個(gè)靜態(tài)的內(nèi)部類,不需要利用關(guān)鍵字new來創(chuàng)建內(nèi)部類的實(shí)例。即在創(chuàng)建靜態(tài)類內(nèi)部對(duì)象時(shí),不需要其外部類的對(duì)象。
java在實(shí)現(xiàn)LinkedList時(shí)使用了如下內(nèi)部類:
public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable { ........ private static class Entry<E> { E element; Entry<E> next; Entry<E> previous; Entry(E element, Entry<E> next, Entry<E> previous) { this.element = element; this.next = next; this.previous = previous; } } private Entry<E> addBefore(E e, Entry<E> entry) { Entry<E> newEntry = new Entry<E>(e, entry, entry.previous); newEntry.previous.next = newEntry; newEntry.next.previous = newEntry; size++; modCount++; return newEntry; } ........ }
這里即靜態(tài)內(nèi)部類的典型用法
java同步工具類
/** * 需要啟動(dòng)多個(gè)線程把接口數(shù)據(jù)分批導(dǎo)入目標(biāo),要求 * 每次執(zhí)行的時(shí)候必須保證前一次任務(wù)已結(jié)束,處理這個(gè)需求的方式有很多種,其實(shí)質(zhì)即 * 線程間同步問題,正好這兩天我也在關(guān)注線程同步相關(guān)的東東,jdk提供了不少的線程 * 同步工具類,CountDownLatch:一個(gè)同步輔助類,在完成一組正在其他線程中執(zhí)行的 * 操作之前,它允許一個(gè)或多個(gè)線程一直等待。 * 用給定的計(jì)數(shù) 初始化 CountDownLatch。由于調(diào)用了 countDown() 方法,所以在當(dāng)前計(jì)數(shù)到達(dá)零之前, * await 方法會(huì)一直受阻塞。之后,會(huì)釋放所有等待的線程,await 的所有后續(xù)調(diào)用都將立即返回。 * 這種現(xiàn)象只出現(xiàn)一次——計(jì)數(shù)無法被重置(這點(diǎn)很重要哦)。如果需要重置計(jì)數(shù),請(qǐng)考慮使用 CyclicBarrier。 * 下面是一個(gè)簡單的例子來模擬該需求,當(dāng)然可能因?yàn)闉榱四M場景,會(huì)有一些不合理的地方,這里主要闡述 * CountDownLatch同步,關(guān)于CountDownLatch的源碼將在后面來分析,其主要涉及AbstractQueuedSynchronizer * 這個(gè)類,他的類容相對(duì)比較復(fù)雜 * **/ import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.concurrent.CountDownLatch; public class Driver { static List<Integer> strList = null; int k = 0; static { //模擬數(shù)據(jù) strList = new ArrayList<Integer>(); for (int i = 0; i < 50; i++) { strList.add(i); } } public static void main(String args[]) { boolean isEnd = true; //為了驗(yàn)證正確性,只執(zhí)行20次 int count=0; Driver d = new Driver(); while (isEnd && strList.size() > 0&&count<20) { CountDownLatch startSignal = new CountDownLatch(1); final CountDownLatch doneSignal = new CountDownLatch(5); for (int i = 0; i < 5; ++i) { new Thread(d.new Worker(startSignal, doneSignal,i)).start(); } //計(jì)數(shù)減1 子線程Worker可以執(zhí)行 startSignal.countDown(); try { new Thread(new Runnable() { Random r = new Random(); @Override public void run() { try { //主線程阻塞 知道所有子線程將doneSignal清零 doneSignal.await(); } catch (InterruptedException e) { e.printStackTrace(); } while(strList.size()<=0){ int pos = r.nextInt(1000); strList.clear(); for (int i = pos; i < pos + 50; i++) { strList.add(i); } } } }).start(); isEnd = true; } catch (Exception e) { e.printStackTrace(); } count++; } } class Worker implements Runnable { private final CountDownLatch startSignal; private final CountDownLatch doneSignal; private int i; Worker(CountDownLatch startSignal, CountDownLatch doneSignal,int i) { this.startSignal = startSignal; this.doneSignal = doneSignal; this.i=i; } public void run() { try { // 等待主線程執(zhí)行countDown startSignal.await(); doWork(); //計(jì)數(shù)減1 doneSignal.countDown(); } catch (InterruptedException ex) { } // return; } void doWork() { synchronized (strList) { int start=(i)*(50/5); int end=(i+1)*(50/5); for (int i = start; i < end; i++) { System.out.println(strList.get(i) + "---" + "已被刪除"); } } } } }
相關(guān)文章
Java 信號(hào)量Semaphore的實(shí)現(xiàn)
這篇文章主要介紹了Java 信號(hào)量Semaphore的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09使用@pathvariable與@requestparam碰到的一些問題及解決
這篇文章主要介紹了使用@pathvariable與@requestparam碰到的一些問題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08基于OpenID?Connect及Token?Relay實(shí)現(xiàn)Spring?Cloud?Gateway
這篇文章主要介紹了基于OpenID?Connect及Token?Relay實(shí)現(xiàn)Spring?Cloud?Gateway,Spring?Cloud?Gateway旨在提供一種簡單而有效的方式來路由到API,并為API提供跨領(lǐng)域的關(guān)注點(diǎn),如:安全性、監(jiān)控/指標(biāo)和彈性2022-06-06Java實(shí)現(xiàn)將容器 Map中的內(nèi)容保存到數(shù)組
這篇文章主要介紹了Java實(shí)現(xiàn)將容器 Map中的內(nèi)容保存到數(shù)組,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-09-09詳解MyBatis的動(dòng)態(tài)SQL實(shí)現(xiàn)原理
MyBatis提供了強(qiáng)大的動(dòng)態(tài)SQL語句生成功能,以應(yīng)對(duì)復(fù)雜的業(yè)務(wù)場景,本篇文章將結(jié)合MyBatis解析SQL語句的過程對(duì)MyBatis中對(duì)<if>,<where>,<foreach>等動(dòng)態(tài)SQL標(biāo)簽的支持進(jìn)行分析,需要的朋友可以參考下2023-07-07Spring Boot處理全局統(tǒng)一異常的兩種方法與區(qū)別
這篇文章主要給大家介紹了關(guān)于Spring Boot處理全局統(tǒng)一異常的兩種方法與區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Spring Boot具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06