Java基礎高級部分(一)


1. 集合部分

1.1 HashMap排序

package cn.Douzi.hashMap01;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map.Entry;
import java.util.Set;

import javax.jws.soap.SOAPBinding.Use;

public class hashMap_demo01 {
    
    public static void main(String[] args) {
    
        HashMap<Integer, User> hashMap = new HashMap<Integer, User>();
        
        User user = new User();
        user.setName("張三");
        user.setAge(23);
        
        hashMap.put(1, user);
        
        User user2 = new User();
        user2.setName("李四");
        user2.setAge(24);
        
        hashMap.put(2, user2);
        
        User user3 = new User();
        user3.setAge(21);
        user3.setName("王五");
        
        hashMap.put(3, user3);
        
        System.out.println("排序前HashMap:" + hashMap);
        
        HashMap<Integer, User> sortedHashMap = sortHashMap(hashMap);
        
        System.out.println("排序后:" + sortedHashMap);
        
        
    }

    private static HashMap<Integer, User> sortHashMap(
            HashMap<Integer, User> hashMap) {
        
        /**
         * 創建一個有序的HashMap數據結構,LinkedHashMap
         */
        LinkedHashMap<Integer, User> newHashMap = new LinkedHashMap<Integer, User>();
        
        //凡是要對集合排序,首先想到的就是集合的工具類
        //把Map結構轉換為list結構
        //把Map轉換為Set集合
        Set<Entry<Integer, User>> entrySet = hashMap.entrySet();
        //把Set集合轉換為List
        ArrayList<Entry<Integer, User>> list = new ArrayList<>(entrySet);
        Collections.sort(list, new Comparator<Entry<Integer, User>>() {

            @Override
            public int compare(Entry<Integer, User> o1, Entry<Integer, User> o2) {
                // TODO Auto-generated method stub
                // -1:正序排序; 前面-后面:正序;后面-前面:倒序
                return o2.getValue().getAge() - o1.getValue().getAge();  
            }
        });
        
        //將排好順序的list轉換為LinkedHashMap
        for (int i = 0; i < list.size(); i++) {
            Entry<Integer, User> entry = list.get(i);
            newHashMap.put(entry.getKey(), entry.getValue());
        }
        
        return newHashMap;
    }
}

2.java中的引用類型

  • 強引用
  • 軟引用:SoftReference
  • 弱引用:WeakReference
  • 虛引用:PhantomReference

對象的可及性:

  • 強可及對象,永遠不會被GC回收
  • 軟可及對象:當系統內存不足的時候,被GC回收。
  • 弱可及對象:當系統GC發現這個對象,就被回收
package cn.Douzi.Reference;

import java.lang.ref.PhantomReference;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;

public class ReferenceTest {
    
    public static void main(String[] args) {
        
        //強引用
//        String str = "abc";    //常量池
        
        //1. 在堆內存中創建了String對象  2.在常量池中創建了abc對象
        String str = new String("abc");
        
        //創建一個軟引用,引用到str
        SoftReference<String> sfr = new SoftReference<String>(str);
        
        //創建一個弱引用,引用到str
        WeakReference<String> wrf = new WeakReference<String>(str);
        
        //虛引用:檢測對象是否被虛擬機回收掉
//        PhantomReference

        //相當於去掉了強引用鏈
        str = null;
        
        //清楚軟引用的引用鏈
        sfr.clear();
        
        System.gc();        //回收了堆內存, 無法回收常量池的內存
        
        String srfString = sfr.get();
        
        String wrfString = wrf.get();
        
        System.out.println("軟引用獲取到的對象:" + srfString);
        System.out.println("弱引用獲取到的對象:" + wrfString);
        
    }
}

 

3. 多線程線程池部分

  • 需求:控制一個方法的並發量,比如 同時只能有5個線程進來
  • 注意:不要用 synchronized,用synchronized關鍵字的兩個線程1和線程2,如果當前線程1獲得鎖,線程2線程等待。如果線程1阻塞,線程2則會一直等待下去。

3.1 使用 Semaphore

package cn.Douzi.Thread_Pool;

import java.lang.reflect.Method;
import java.util.concurrent.Semaphore;

public class ThreadPoolTest {
    
    //信號量
    private static Semaphore semaphore = new Semaphore(5);  //允許個數, 相當於放了5把鎖
    
    public static void main(String[] args) {
        
        
        for (int i = 0; i < 100; i++) {
            new Thread(new Runnable() {
                
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    try {
                        method();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }).start();
        }
    }
    
    //同時最多只運行5個進程過來
    public static  void method() throws InterruptedException {

        semaphore.acquire();    //獲取一把鎖
        
        System.out.println("ThreadName" + Thread.currentThread().getName()+"進來了");
        
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        System.out.println("ThreadName="+Thread.currentThread().getName()+"出去了");
        
        semaphore.release();  //釋放一把鎖
      
    }

}

3.2 線程池

線程池的啟動策略

系統自帶的線程池

 

//網絡訪問框架,都要用線程池
    private static Executor executors = Executors.newCachedThreadPool(); //緩存線程池
    private static Executor executor2 = Executors.newFixedThreadPool(5); //固定線程個數的線程
    private static Executor executor3 = Executors.newScheduledThreadPool(5); //計划任務線程池
    private static Executor executor4 = Executors.newSingleThreadExecutor(); //單個線程的線程池

 

手寫線程池

/* * 參數1:corePoolSize:核心池大小 * 參數2:maximumPoolSize:最大線程池上限個數 * 參數3:keepAliveTime:保存最長時間,任務執行完之后,要裁員的延時 * 參數4:unit:時間單位 * 參數5:workQueue:用於存儲任務的工作隊列(即將被執行的任務)(BlockingQueue) * 參數6:ThreadFactory: 線程工廠, 用來創建線程的 * */
ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(5, 10, 1, TimeUnit.SECONDS, blockingQueue, threadFactlory);

創建一個線程工廠

ThreadFactory threadFactlory = new ThreadFactory() { //線程安全的int的包裝類 AtomicInteger atomicInteger = new AtomicInteger(0); @Override public Thread newThread(Runnable r) { //創建一個線程,然后把r賦值給該線程 Thread thread = new Thread(r); thread.setName("MyThread=" + atomicInteger.getAndIncrement()); return thread; }
};

完整創建核心池

package cn.Douzi.Thread_Pool; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.LinkedList; import java.util.concurrent.BlockingQueue; import java.util.concurrent.Executor; import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.Semaphore; import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; public class ThreadPoolTest02 { //網絡訪問框架,都要用線程池
    private static Executor executors = Executors.newCachedThreadPool(); //緩存線程池
    private static Executor executor2 = Executors.newFixedThreadPool(5); //固定線程個數的線程
    private static Executor executor3 = Executors.newScheduledThreadPool(5); //計划任務線程池
    private static Executor executor4 = Executors.newSingleThreadExecutor(); //單個線程的線程池
    
    
    public static void main(String[] args) { // BlockingQueue<E> //單端隊列 // BlockingDQueue //雙端隊列
        LinkedBlockingQueue<Runnable> blockingQueue = new LinkedBlockingQueue<>(100); //該容器的最大上限 //創建一個線程工廠
        ThreadFactory threadFactlory = new ThreadFactory() { //線程安全的int的包裝類
            AtomicInteger atomicInteger = new AtomicInteger(0); @Override public Thread newThread(Runnable r) { //創建一個線程,然后把r賦值給該線程
                Thread thread = new Thread(r); thread.setName("MyThread=" + atomicInteger.getAndIncrement()); return thread; } }; /* * 參數1:corePoolSize:核心池大小 * 參數2:maximumPoolSize:最大線程池上限個數 * 參數3:keepAliveTime:保存最長時間,任務執行完之后,要裁員的延時 * 參數4:unit:時間單位 * 參數5:workQueue:用於存儲任務的工作隊列(即將被執行的任務)(BlockingQueue) * 參數6:ThreadFactory: 線程工廠, 用來創建線程的 * */ ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(5, 10, 1, TimeUnit.SECONDS, blockingQueue, threadFactlory); /** * 線程不是越多越好,Google工程給了一個推薦值:線程的個數=CPU核心數+1=5 */
        
        //用自己打造的線程池
        for (int i = 0; i < 110; i++) { poolExecutor.execute(new Runnable() { @Override public void run() { // TODO Auto-generated method stub
                    try { method(); } catch (InterruptedException e) { // TODO Auto-generated catch block
 e.printStackTrace(); } } }); } //用系統自帶的線程池 // for (int i = 0; i < 100; i++) { // executor2.execute(new Runnable() { //                
// @Override // public void run() { //                    // TODO Auto-generated method stub // try { // method(); // } catch (InterruptedException e) { //                        // TODO Auto-generated catch block // e.printStackTrace(); // } // } // }); // }
 } //同時最多只運行5個進程過來
    public static  void method() throws InterruptedException { System.out.println("ThreadName= " + Thread.currentThread().getName()+"進來了"); try { Thread.sleep(2000); } catch (InterruptedException e) { // TODO Auto-generated catch block
 e.printStackTrace(); } System.out.println("ThreadName= "+Thread.currentThread().getName()+"出去了"); } }

注意:核心池為0,執行完會自動退出;核心池 > 0不會被退出。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM