CodeForces - 967D Resource Distribution(貪心+二分+構造)
阿新 • • 發佈:2020-12-14
技術標籤:java
執行緒與程序
程序:是指一個記憶體中執行的應用程式,每個程序都有一個獨立的記憶體空間
執行緒:
- 是程序中的一個執行路徑,共享一個記憶體空間,執行緒之間可以自由切換,併發執行. 一個程序最少有一個執行緒
- 執行緒實際上是在程序基礎之上的進一步劃分,一個程序啟動之後,裡面的若干執行路徑又可以劃分成若干個執行緒
執行緒池 Executors
如果併發的執行緒數量很多,並且每個執行緒都是執行一個時間很短的任務就結束了,這樣頻繁建立執行緒 就會大大降低 系統的效率,因為頻繁建立執行緒和銷燬執行緒需要時間. 執行緒池就是一個容納多個執行緒的容 器,池中的執行緒可以反覆使用,省去了頻繁建立執行緒物件的操作,節省了大量的時間和資源
執行緒池的好處
- 降低資源消耗。
- 提高響應速度。
- 提高執行緒的可管理性。
Java中的四種執行緒池 . ExecutorService
- 快取執行緒池
/*** 快取執行緒池.
* (長度無限制) * 執行流程:
* 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());
}
});
- 定長執行緒池
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. 判斷執行緒池的那個執行緒是否空閒
* 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());
}
});
- 週期性任務定長執行緒池
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使用步驟
- 編寫類實現Callable介面 , 實現call方法
class XXX implements Callable<T> {
@Override
public <T> call() throws Exception {
return T;
}
}
- 建立FutureTask物件 , 並傳入第一步編寫的Callable類物件
FutureTask<Integer> future = new FutureTask<>(callable);
- 通過Thread,啟動執行緒
new Thread(future).start();
Runnable 與 Callable的相同點
-
Runnable沒有返回值;Callable可以返回執行結果
-
Callable介面的call()允許丟擲異常;Runnable的run()不能丟擲
Callable獲取返回值
Callalble介面支援返回執行結果,需要呼叫FutureTask.get()得到,此方法會阻塞主程序的繼續往下執
行,如果不呼叫不會阻塞。