1. 程式人生 > 其它 >CodeForces - 967D Resource Distribution(貪心+二分+構造)

CodeForces - 967D Resource Distribution(貪心+二分+構造)

技術標籤:java

執行緒與程序

程序:是指一個記憶體中執行的應用程式,每個程序都有一個獨立的記憶體空間
執行緒:

  1. 是程序中的一個執行路徑,共享一個記憶體空間,執行緒之間可以自由切換,併發執行. 一個程序最少有一個執行緒
  2. 執行緒實際上是在程序基礎之上的進一步劃分,一個程序啟動之後,裡面的若干執行路徑又可以劃分成若干個執行緒

執行緒池 Executors

如果併發的執行緒數量很多,並且每個執行緒都是執行一個時間很短的任務就結束了,這樣頻繁建立執行緒 就會大大降低 系統的效率,因為頻繁建立執行緒和銷燬執行緒需要時間. 執行緒池就是一個容納多個執行緒的容 器,池中的執行緒可以反覆使用,省去了頻繁建立執行緒物件的操作,節省了大量的時間和資源

執行緒池的好處

  1. 降低資源消耗。
  2. 提高響應速度。
  3. 提高執行緒的可管理性。

Java中的四種執行緒池 . ExecutorService

  1. 快取執行緒池
/*** 快取執行緒池.
     * (長度無限制) * 執行流程:
     * 1. 判斷執行緒池是否存在空閒執行緒
     * 2. 存在則使用
     * 3. 不存在,則建立執行緒 並放入執行緒池, 然後使用
     * */
    ExecutorService service = Executors.newCachedThreadPool();//向執行緒池中 加入 新的任務
    service.execute(new Runnable
() { @Override public void run() { System.out.println("執行緒的名稱:"+Thread.currentThread().getName()); } }); service.execute(new Runnable() { @Override public void run() { System.out.println("執行緒的名稱:"+Thread.
currentThread().getName()); } }); service.execute(new Runnable() { @Override public void run() { System.out.println("執行緒的名稱:"+Thread.currentThread().getName()); } });
  1. 定長執行緒池
ExecutorService service = Executors.newFixedThreadPool(2); 
    service.execute(new Runnable() { 
        @Override 
        public void run() { 
            System.out.println("執行緒的名稱:"+Thread.currentThread().getName()); 
        }
    }); 
    service.execute(new Runnable() { 
        @Override 
        public void run() {
            System.out.println("執行緒的名稱:"+Thread.currentThread().getName());
        } 
    });
  1. 單執行緒執行緒池
//效果與定長執行緒池 建立時傳入數值1 效果一致.
            /**
             * 單執行緒執行緒池.
             * 執行流程:
             * 1. 判斷執行緒池的那個執行緒是否空閒
             * 2. 空閒則使用
             * 3. 不空閒,則等待池中的單個執行緒空閒後使用 
             * */ 
            ExecutorService service = Executors.newSingleThreadExecutor();
            service.execute(new Runnable() { 
                @Override 
        public void run() { 
                    System.out.println("執行緒的名稱:"+Thread.currentThread().getName());
                }
            });
            service.execute(new Runnable() { 
                @Override 
        public void run() { 
                    System.out.println("執行緒的名稱:"+Thread.currentThread().getName());
                } 
            });
  1. 週期性任務定長執行緒池
ScheduledExecutorService service = Executors.newScheduledThreadPool(2);
        /**
         * 定時執行
         * 引數1. runnable型別的任務
         * 引數2. 時長數字
         * 引數3. 時長數字的單位
         * */
        service.schedule(new Runnable() {
            @Override public void run() {
                System.out.println("你倆幹哈呢!");
            }
            },5,TimeUnit.SECONDS);
        /** 週期執行
         * 引數1. runnable型別的任務
         * 引數2. 時長數字(延遲執行的時長)
         * 引數3. 週期時長(每次執行的間隔時間)
         * 引數4. 時長數字的單位
         * */
        service.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                System.out.println("跟誰倆呢!");
            }
            },5,2,TimeUnit.SECONDS); }

Runnable 與 Callable

//Callable介面 
     public interface Callable<V> { 
        V call() throws Exception; 
    }
    //Runnable介面 
    public interface Runnable { 
         public abstract void run(); 
     }

Callable使用步驟

  1. 編寫類實現Callable介面 , 實現call方法
class XXX implements Callable<T> { 
	@Override 
		public <T> call() throws Exception { 
			return T; 
			}
		} 
  1. 建立FutureTask物件 , 並傳入第一步編寫的Callable類物件
FutureTask<Integer> future = new FutureTask<>(callable); 
  1. 通過Thread,啟動執行緒
new Thread(future).start();

Runnable 與 Callable的相同點

  1. Runnable沒有返回值;Callable可以返回執行結果

  2. Callable介面的call()允許丟擲異常;Runnable的run()不能丟擲

Callable獲取返回值

Callalble介面支援返回執行結果,需要呼叫FutureTask.get()得到,此方法會阻塞主程序的繼續往下執
行,如果不呼叫不會阻塞。