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

資訊專欄INFORMATION COLUMN

【J2SE】java并發基礎

tianyu / 1978人閱讀

摘要:的線程機制是搶占式。會讓出當多個線程并發的對主存中的數據進行操作時,有且只有一個會成功,其余均失敗。和對象只有在困難的多線程問題中才是必須的。

并發簡述

并發通常是用于提高運行在單處理器上的程序的性能。在單 CPU 機器上使用多任務的程序在任意時刻只在執行一項工作。

并發編程使得一個程序可以被劃分為多個分離的、獨立的任務。一個線程就是在進程中的一個單一的順序控制流。java的線程機制是搶占式。

線程的好處是提供了輕量級的執行上下文切換,只改變了程序的執行序列和局部變量。

多線程的主要缺陷:

等待共享資源的時候性能降低。

需要處理線程的額外 CPU 花費。

糟糕的程序設計導致不必要的復雜度。

有可能產生一些病態行為,若餓死、競爭、死鎖和活鎖。

不同平臺導致的不一樣。

volatile關鍵字

源來

當程序運行,JVM會為每一個線程分配一個獨立的緩存用于提高執行效率,每一個線程都在自己獨立的緩存中操作各自的數據。一個線程在緩沖中對數據進行修改,寫入到主存后,其他線程無法得知數據已被更改,仍在操作緩存中已過時的數據,為了解決這個問題,提供了volatile關鍵字,實現內存可見,一旦主存數據被修改,便致使其他線程緩存數據行無效,強制前往主存獲取新數據。

Example:內存不可見,導致主線程無法結束。

class ThreadDemo implements Runnable {
    //添加volatile關鍵字可實現內存可見性 public volatile boolean flag = false;
    public boolean flag = Boolean.false;
    
    @Override
    public void run() {
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
        }
        flag = Boolean.true;
        System.out.println("ThreadDemo over");
    }
    
    public boolean isFlag() {
        return flag;
    }
}

public class TestVolatile {

    public static void main(String[] args) {
        ThreadDemo demo = new ThreadDemo();
        new Thread(demo).start();
        
        while (true) {
            if (demo.flag || demo.isFlag()) {
                System.out.println("Main over");
                break;
            }
        }
    }
}/*output:打印ThreadDemo over,主線程持續循環*/

作用:

當多個線程操作共享數據時,保證內存中的數據可見性。采用底層的內存柵欄,及時的將緩存中修改的數據刷新到主存中,并導致其他線程所緩存的數據無效,使得這些線程必須去主存中獲取修改的數據。

優缺點:

保證內存可見性,讓各個線程能夠彼此獲取最新的內存數據。

較傳統synchronized加鎖操作提高了效率,若有線程正在操作被synchronized修飾的代碼塊數據時,其他線程試圖進行操作,發現已被其他線程占用,試圖操作的線程必須掛起,等到下一次繼續嘗試操作。

對volatile修飾的數據被修改后,其他線程必須前往主存中讀取,若修改頻繁,需要不斷讀取主存數據,效率將會降低。

使用volatile,底層采用內存柵欄,JVM將不會對其提供指令重排序及其優化。

不具備互斥性。多個線程可以同時對數據進行操作,只是由原來的在緩存操作轉變成了直接在主存中操作。(synchronized是互斥的,一個線程正在執行,其他線程必須掛起等待)

不保證變量的原子性。使用volatile僅僅是一個能保證可見性的輕量級同步策略。

原子變量與 CAS 算法

Example:使用volatile修飾,number自增問題。

class ThreadDemo implements Runnable {
    public volatile int number = 0;
    
    @Override
    public void run() {
        try {
            Thread.sleep(200);
        } catch (Exception e) {
        }
        System.out.print(getIncrementNumber() + " ");
    }
    
    public int getIncrementNumber() {
        return ++number;
    }
}

public class TestAtomic {
    public static void main(String[] args) {
        ThreadDemo demo = new ThreadDemo();
        for (int i = 0; i < 10; i++) {
            new Thread(demo).start();
        }
    }
}/*output: 1 5 4 7 3 9 2 1 8 6 */
//    ++number底層原理思想
int temp = number;        // ①
number = number + 1;    // ②
temp = number;            // ③
return temp;            // ④

由 ++number 可知,返回的是 temp 中存儲的值,且自增是一個多步操作,當多個線程調用 incrementNumber方法時,方法去主存中獲取 number 值放入 temp 中,根據 CPU 時間片切換,當 A 線程完成了 ③ 操作時,時間片到了被中斷,A 線程開始執行 ① 時不幸被中斷,接著 A 獲取到了CPU執行權,繼續執行完成 ④ 操作更新了主存中的值,緊接著 B 線程開始執行,但是 B 線程 temp中存儲的值已經過時了。注意:自增操作為四步,只有在第四步的時候才會刷新主存的值,而不是number = number + 1 操作就反映到主存中去。如圖所示:

源來:

volatile只能保證內存可見性,對多步操作的變量,無法保證其原子性,為了解決這個問題,提供了原子變量。

作用:

原子變量既含有volatile的內存可見性,又提供了對變量原子性操作的支持,采用底層硬件對并發操作共享數據的 CAS(Compare-And-Swap)算法,保證數據的原子性。

提供的原子類:

描述
AtomicBoolean 一個 boolean值可以用原子更新。
AtomicInteger 可能原子更新的 int值。
AtomicIntegerArray 一個 int數組,其中元素可以原子更新。
AtomicIntegerFieldUpdater 基于反射的實用程序,可以對指定類的指定的 volatile int字段進行原子更新。
AtomicLong 一個 long值可以用原子更新。
AtomicLongArray 可以 long地更新元素的 long數組。
AtomicLongFieldUpdater 基于反射的實用程序,可以對指定類的指定的 volatile long字段進行原子更新。
AtomicMarkableReference AtomicMarkableReference維護一個對象引用以及可以原子更新的標記位。
AtomicReference 可以原子更新的對象引用。
AtomicReferenceArray 可以以原子方式更新元素的對象引用數組。
AtomicReferenceFieldUpdater 一種基于反射的實用程序,可以對指定類的指定的 volatile volatile引用原子更新。
AtomicStampedReference AtomicStampedReference維護對象引用以及可以原子更新的整數“印記”。
DoubleAccumulator 一個或多個變量一起維護使用提供的功能更新的運行的值 double
DoubleAdder 一個或多個變量一起保持初始為零 double和。
LongAccumulator 一個或多個變量,它們一起保持運行 long使用所提供的功能更新值。
LongAdder 一個或多個變量一起保持初始為零 long總和。

CAS算法:

CAS(Compare-And-Swap)是底層硬件對于原子操作的一種算法,其包含了三個操作數:內存值(V),預估值(A),更新值(B)。當且僅當 V == A 時, 執行 V = B 操作;否則不執行任何結果。這里需要注意,A 和 B 兩個操作數是原子性的,同一時刻只能有一個線程進行AB操作。

優缺點:

操作失敗時,直接放棄結果,并不釋放對CPU的控制權,進而可以繼續嘗試操作,不必掛起等待。(synchronized會讓出CPU)

當多個線程并發的對主存中的數據進行操作時,有且只有一個會成功,其余均失敗。

原子變量中封裝了用于對數據的原子操作,簡化了代碼的編寫。

Collection并發類

HashMap 與 HashTable簡述

HashMap是線程不安全的,而HashTable是線程安全的,因為HashTable所維護的Hash表存在著獨占鎖,當多個線程并發訪問時,只能有一個線程可進行操作,但是對于復合操作時,HashTable仍然存在線程安全問題,不使用HashTable的主要原因還是效率低下。

// 功能:不包含obj,則添加
if (!hashTable.contains(obj)) {
    // 復合操作,執行此處時線程中斷,obj被其他線程添加至容器中,此處繼續執行將導致重復添加
    hashTable.put(obj);
}

可知上述兩個操作需要 “原子性”,為了達到效果,還不是得對代碼塊進行同步

ConcurrentHashMap

采用鎖分段機制,分為 16 個段(并發級別),每一個段下有一張表,該表采用鏈表結構鏈接著各個元素,每個段都使用獨立的鎖。當多個線程并發操作的時候,根據各自的級別不同,操作不同的段,多個線程并行操作,明顯提高了效率,其次還提供了復合操作的諸多方法。注:jdk1.8由原來的數組+單向鏈表結構轉換成數據+單向鏈表+紅黑樹結構。

ConcurrentSkipListMap和ConcurrentSkipListSet

有序的哈希表,通過跳表實現,不允許null作為鍵或值。ConcurrentSkipListMap詳解

CopyOnWriteArrayList 和 CopyOnWriteArraySet

對collection進行寫入操作時,將導致創建整個底層數組的副本,而源數組將保留在原地,使得復制的數組在被修改時,讀取操作可以安全的執行。當修改完成時,一個原子性的操作將把心的數組換人,使得新的讀取操作可以看到新的修改。

好處之一是當多個迭代器同時遍歷和修改列表時,不會拋出ConcurrentModificationException。

小結:

當期望許多線程訪問一個給定 collection 時,ConcurrentHashMap 通常優于同步的 HashMap

ConcurrentSkipListMap 通常優于同步的 TreeMap。

當期望的讀數和遍歷遠遠大于列表的更新數時,CopyOnWriteArrayList 優于同步的 ArrayList。

并發迭代操作多時,可選擇CopyOnWriteArrayList 和 CopyOnWriteArraySet。

高并發情況下,可選擇ConcurrentSkipListMap和ConcurrentSkipListSet

CountDownLatch閉鎖

源由:

當一個修房子的 A 線程正在執行,需要磚頭時,開啟了一個線程 B 去拉磚頭,此時 A 線程需要等待 B 線程的結果后才能繼續執行時,但是線程之間都是并行操作的,為了解決這個問題,提供了CountDownLatch。

作用:

一個同步輔助類,為了保證執行某些操作時,“所有準備事項都已就緒”,僅當某些操作執行完畢后,才能執行后續的代碼塊,否則一直等待。

CountDownLatch中存在一個鎖計數器,如果鎖計數器不為 0 的話,它會阻塞任何一個調用 await() 方法的線程。也就是說,當一個線程調用 await() 方法時,如果鎖計數器不等于 0,那么就會一直等待鎖計數器為 0 的那一刻,這樣就解決了需要等待其他線程執行完畢才執行的需求。

Example:

class ThreadDemo implements Runnable {
    private CountDownLatch latch = null;

    public ThreadDemo(CountDownLatch latch) {
        this.latch = latch;
    }

    @Override
    public void run() {
        try {
            System.out.println("execute over");
        } finally {
            latch.countDown();    // 必須保證計數器減一
        }
    }
}
public class TestCountDownLatch {

    public static void main(String[] args) {
        final int count = 10;
        final CountDownLatch latch = new CountDownLatch(count);
        ThreadDemo demo = new ThreadDemo(latch);
        for (int i = 0; i < count; ++i) {
            new Thread(demo).start();
        }
        
        try {
            latch.await();    // 等待計數器為 0
            System.out.println("其他線程結束,繼續往下執行...");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}/**output:
    execute over
    ...
    其他線程結束,繼續往下執行...
*/

細節:

子線程完畢后,必須調用 countDown() 方法使得 鎖計數器減一,否則將會導致調用 await() 方法的線程持續等待,盡可能的放置在 finally 中。

鎖計數器的個數與子線程數最好相等,只要計數器等于 0,不論是否還存在子線程,await() 方法將得到響應,繼續執行后續代碼。

Callable接口

源由:

當開啟一個線程執行運算時,可能會需要該線程的計算結果,之前的 implements Runnableextends Thread 的 run() 方法并沒有提供可以返回的功能,因此提供了 Callable接口。 Callable 的運行結果, 需要使用 FutureTask 類來接受。

Example:

class ThreadDemo implements Callable {
    private Integer cycleValue;
    
    public ThreadDemo(Integer cycleValue) {
        this.cycleValue = cycleValue;
    }
    
    @Override
    public Integer call() throws Exception {
        int result = 0;
        for (int i=0; i task = new FutureTask<>(demo);
        new Thread(task).start();
        
        Integer result = task.get();    // 等待計算結果返回, 閉鎖
        System.out.println(result);
    }
}/*output:1073741825 */
Lock同步鎖和Condition線程通信控制對象
Lock:在進行性能測試時,使用Lock通常會比使用synchronized要高效許多,并且synchronized的開銷變化范圍很大,而Lock相對穩定。只有在性能調優時才使用Lock對象。

Condition: 替代了 Object 監視器方法的使用,描述了可能會與鎖有關的條件標量,相比 Object 的 notifyAll() ,Condition 的 signalAll() 更安全。Condition 實質上被綁定到一個鎖上,使用newCondition() 方法為 Lock 實例獲取 Condition。

Lock和Condition對象只有在困難的多線程問題中才是必須的。

synchonized與Lock的區別:

synchonized Lock
隱式鎖 顯示鎖
JVM底層實現,由JVM維護 由程序員手動維護
靈活控制(也有風險)

“虛假喚醒”:當一個線程A在等待時,被另一個線程喚醒,被喚醒的線程不一定滿足了可繼續向下執行的條件,如果被喚醒的線程未滿足條件,而又向下執行了,那么稱這個現象為 “虛假喚醒”。

//    安全的方式,保證退出等待循環前,一定能滿足條件
while (條件) {
    wait();
}

Example:生產消費者

// 產品car
class Car {
    private Lock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();
    private boolean available = false; // false:無貨;true有貨

    public void put(){
        lock.lock();
        try {
            while (available) {        // 有貨等待
                condition.await();
            }
            System.out.println(Thread.currentThread().getName() + "put():    進貨");
            available = true;
            condition.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void get() {
        lock.lock();
        try {
            while (!available) {    // 無貨等待
                condition.await();
            }
            System.out.println(Thread.currentThread().getName() + "get():出貨");
            available = false;
            condition.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

}
// 消費者
class Consume implements Runnable {
    private Car car;
    
    public Consume(Car car) {
        this.car = car;
    }

    @Override
    public void run() {
        for (int i=0; i
每一個 對lock()的調用都必須緊跟著一個 try-finally 子句,用以保證可以在任何情況下都能釋放鎖,任務在調用 await()signal()signalAll()之前,必須擁有鎖。
lock.lock();
try {
    ...    // 業務代碼
} finally {
    lock.unlock();
}
ReadWriteLock讀寫鎖

源由:

上述講解的鎖都是讀寫一把鎖,不論是讀或寫,都是一把鎖解決,當多線程訪問數據時,若發生了一千次操作,其中的寫操作只執行了一次,數據的更新率非常低,那么每次進行讀操作時,都要加鎖讀取”不會更改的“數據,顯然是不必要的開銷,因此出現了 ReadWriteLock 讀寫鎖,該對象提供讀鎖和寫鎖。

作用:

ReadWriteLock 維護了一對相關的鎖,一個用于只讀操作,另一個用于寫入操作。只要沒有 write寫入操作,那么多個線程可以同時進行持有讀鎖。而寫入鎖是獨占的,當執行寫操作時,其他線程不可寫,也不可讀。

性能的提升取決于讀寫操作期間讀取數據相對于修改數據的頻率,如果讀取操作遠遠大于寫入操作時,便能增強并發性。

Example:

class Demo {
    private int value = 0;
    private ReadWriteLock lock = new ReentrantReadWriteLock();
    
    public void read() {
        lock.readLock().lock();
        try {
            System.out.println(Thread.currentThread().getName() + " : " + value);
        } finally {
            lock.readLock().unlock();
        }
    }
    
    public void write(int value) {
        lock.writeLock().lock();
        try {
            this.value = value;
            System.out.println("write(" + value + ")");
        } finally {
            lock.writeLock().unlock();
        }
    }
}
class ReadLock implements Runnable {
    private Demo demo = null;
    
    public ReadLock(Demo demo) {
        this.demo = demo;
    }
    
    @Override
    public void run() {
        for (int i=0; i<20; ++i) {
            demo.read();
            try {
                Thread.sleep(320);
            } catch (InterruptedException e) {
            }
        }
    }
    
}
class WriteLock implements Runnable {
    private Demo demo = null;
    
    public WriteLock(Demo demo) {
        this.demo = demo;
    }
    
    @Override
    public void run() {
        for (int i=0; i<10; ++i) {
            demo.write(i);
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
            }
        }
    }
    
}
public class TestReadWriteLock {
    
    public static void main(String[] args) {
        Demo demo = new Demo();
        ReadLock readLock = new ReadLock(demo);
        WriteLock writeLock = new WriteLock(demo);
        for (int i=0; i<3; ++i) {
            new Thread(readLock, i + "--").start();
        }
        new Thread(writeLock).start();
    }
}/**output:
    0-- : 0
    1-- : 0
    2-- : 0
    write(0)
    write(1)
    1-- : 1
    2-- : 1
    0-- : 1
    write(2)
    write(3)
    1-- : 3
    0-- : 3
    ...
*/
線程池與線程調度

源來:

在傳統操作中(如連接數據庫),當我們需要使用一個線程的時候,就 直接創建一個線程,線程完畢后被垃圾收集器回收。每一次需要線程的時候,不斷的創建與銷毀,大大增加了資源的開銷。

作用:

線程池維護著一個線程隊列,該隊列中保存著所有等待著的線程,避免了重復的創建與銷毀而帶來的開銷。

體系結構:

Execuotr:負責線程的使用與調度的根接口。
    |- ExecutorService:線程池的主要接口。
        |- ForkJoinPool:采用分而治之技術將任務分解。
        |- ThreadPoolExecutor:線程池的實現類。
        |- ScheduledExecutorService:負責線程調度的子接口。
            |- ScheduledThreadPoolExecutor:負責線程池的調度。繼承ThreadPoolExecutor并實現ScheduledExecutorService接口

Executors 工具類API描述:

方法 描述
ExecutorService newFixedThreadPool(int nThreads) 創建一個可重用固定數量的無界隊列線程池。使用了有限的線程集來執行所提交的所有任務。創建的時候可以一次性預先進行代價高昂的線程分配。
ExecutorService newWorkStealingPool(int parallelism) 創建一個維護足夠的線程以支持給定的parallelism并行級別的線程池。
ExecutorService newSingleThreadExecutor() 創建一個使用單個線程運行的無界隊列的執行程序。
ExecutorService newCachedThreadPool() 創建一個根據需要創建新線程的線程池,當有可用線程時將重新使用以前構造的線程。
ScheduledExecutorService newSingleThreadScheduledExecutor() 創建一個單線程執行器,可以調度命令在給定的延遲之后運行,或定期執行。
ScheduledExecutorService newScheduledThreadPool(int corePoolSize) 創建一個線程池,可以調度命令在給定的延遲之后運行,或定期執行。
ThreadFactory privilegedThreadFactory() 返回一個用于創建與當前線程具有相同權限的新線程的線程工廠。

補充:

ExecutorService.shutdown():防止新任務被提交,并繼續運行被調用之前所提交的所有任務,待任務都完成后退出。

CachedThreadPoo在程序執行過程中通常會創建與所需數量相同的線程,然后在它回收舊線程時停止創建新線程,是Executor的首選。僅當這個出現問題時,才需切換 FixedThreadPool。

SingleThreadExecutor: 類似于線程數量為 1 的FixedThreadPool,但它提供了不會存在兩個及以上的線程被并發調用的并發。

Example:線程池

public class TestThreadPool {

    public static void main(String[] args) throws Exception {
        ExecutorService pool = Executors.newFixedThreadPool(2);
        for (int i = 0; i < 10; ++i) {
            Future future = pool.submit(new Callable() {

                @Override
                public String call() throws Exception {
                    return Thread.currentThread().getName();
                }
                
            });

            String threadName = future.get();
            System.out.println(threadName);
        }
        pool.shutdown();    // 拒絕新任務并等待正在執行的線程完成當前任務后關閉。
    }
}/**output:
    pool-1-thread-1
    pool-1-thread-2
    pool-1-thread-1
    pool-1-thread-2
    ...
*/

Example:線程調度

public class TestThreadPool {

    public static void main(String[] args) throws Exception {
        ScheduledExecutorService pool = Executors.newScheduledThreadPool(2);
        for (int i = 0; i < 5; ++i) {
            ScheduledFuture future = pool.schedule(new Callable() {
    
                @Override
                public String call() throws Exception {
                    return Thread.currentThread().getName() + " : " + Instant.now();
                }
            }, 1, TimeUnit.SECONDS);    // 延遲執行單位為 1秒的任務
            
            String result = future.get();
            System.out.println(result);
        }
        pool.shutdown();
    }
}/**output:
    pool-1-thread-1 : 2019-03-18T12:10:31.260Z
    pool-1-thread-1 : 2019-03-18T12:10:32.381Z
    pool-1-thread-2 : 2019-03-18T12:10:33.382Z
    pool-1-thread-1 : 2019-03-18T12:10:34.383Z
    pool-1-thread-2 : 2019-03-18T12:10:35.387Z
*/

注意:若沒有執行 shutdown()方法,則線程會一直等待而不停止。

ForkJoinPool分支/合并框架

源由:

在一個線程隊列中,假如隊頭的線程由于某種原因導致了阻塞,那么在該隊列中的后繼線程需要等待隊頭線程結束,只要隊頭一直阻塞,這個隊列中的所有線程都將等待。此時,可能其他線程隊列都已經完成了任務而空閑,這種情況下,就大大減少了吞吐量。

ForkJoin的“工作竊取”模式:

當執行一個新任務時,采用分而治之的思想,將其分解成更小的任務執行,并將分解的任務加入到線程隊列中,當某一個線程隊列沒有任務時,會隨機從其他線程隊列中“偷取”一個任務,放入自己的隊列中執行。

Example:

// 求次方: value為底,size為次方數
class CountPower extends RecursiveTask {
    private static final long serialVersionUID = 1L;
    public Long value = 0L;
    public int size = 0;
    public static final Long CRITICAL = 10L;     // 閾值
    
    public CountPower(Long value, int size) {
        this.value = value;
        this.size = size;
    }

    @Override
    protected Long compute() {
        // 當要開方的此時 小于 閾值,則計算 (視為最小的任務單元)
        if(size <= CRITICAL) {
            Long sum = 1L;
            for (int i=0; i

根據分而治之的思想進行分解,需要一個結束遞歸的條件,該條件內的代碼就是被分解的最小單元。使用fork()在當前任務正在運行的池中異步執行此任務,即將該任務壓入線程隊列。調用join()`返回計算結果。RecursiveTask是有返回值的task,RecursiveAction則是沒有返回值的。

參考

尚硅谷JUC視頻教程

《java編程思想》第 21 章 并發

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/73784.html

相關文章

  • J2SEjava并發編程實戰 讀書筆記( 一、二、三章)

    摘要:發布的對象內部狀態可能會破壞封裝性,使程序難以維持不變性條件。不變性線程安全性是不可變對象的固有屬性之一。可變對象必須通過安全方式來發布,并且必須是線程安全的或者有某個鎖保護起來。 線程的優缺點 線程是系統調度的基本單位。線程如果使用得當,可以有效地降低程序的開發和維護等成本,同時提升復雜應用程序的性能。多線程程序可以通過提高處理器資源的利用率來提升系統的吞吐率。與此同時,在線程的使用...

    QLQ 評論0 收藏0
  • 聊聊 Java8 以后各個版本的新特性

    摘要:于是抽時間看了看以后各個版本的特性,做了一個總結。年和公開版本發布,取名為。此后對應版本就是,。發布,是一個重大版本更新。在此之后,就是每六個月發布一次新版本。以上和參考資料聊了一些關于的歷史,下面我們看看各個版本有那些新特性。 【這是 ZY 第 11 篇原創技術文章】 某天在網上閑逛,突然看到有篇介紹 Java 11 新特性的文章,頓時心里一驚,畢竟我對于 Java 的版本認識...

    K_B_Z 評論0 收藏0
  • Java新手的一些建議——Java知識點歸納(Java基礎部分)

    摘要:中很多特性或者說知識點都是和面向對象編程概念相關的。在多線程中內容有很多,只是簡單說明一下中初步使用多線程需要掌握的知識點,以后有機會單獨再詳細介紹一些高級特性的使用場景。   寫這篇文章的目的是想總結一下自己這么多年來使用java的一些心得體會,主要是和一些java基礎知識點相關的,所以也希望能分享給剛剛入門的Java程序員和打算入Java開發這個行當的準新手們,希望可以給大家一些經...

    lykops 評論0 收藏0
  • J2SEjava NIO 基礎學習

    摘要:標記,表示記錄當前的位置。直接緩沖通過方法分配的緩沖區,此緩沖區建立在物理內存中。直接在兩個空間中開辟內存空間,創建映射文件,去除了在內核地址空間和用戶地址空間中的操作,使得直接通過物理內存傳輸數據。 NIO與IO的區別 IO NIO 阻塞式 非阻塞式、選擇器selectors 面向流:單向流動,直接將數據從一方流向另一方 面向緩存:將數據放到緩存區中進行存取,經通道進行...

    yexiaobai 評論0 收藏0
  • Java編程基礎01——計算機基礎

    摘要:外部存儲器可用于長期保存大量程序和數據,其成本低容量大,但速度較慢。 1_計算機概述(了解) A:什么是計算機?計算機在生活中的應用舉例 計算機(Computer)全稱:電子計算機,俗稱電腦。是一種能夠按照程序運行,自動、高速處理海量數據的現代化智能電子設備。由硬件和軟件所組成,沒有安裝任何軟件的計算機稱為裸機。常見的形式有臺式計算機、筆記本計算機、大型計算機等。 應用舉例 ...

    xiangzhihong 評論0 收藏0

發表評論

0條評論

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