1.如果控制一個線程的執行順序
①.join()方法
join 讓主線程等待子線程結束以後才能繼續執行
②使用線程池來解決
使用單一線程池的特性來解決。
synchronized
- synchronized 方法上
一旦有線程進入這個方法 類的所有非靜態(注意 是非靜態 )的同步方法 以及其他的用這個對象鎖定的代碼都無法進入。
- synchronized(this) 內部
synchronized鎖住的是括號裏的對象,而不是代碼。對於非static的synchronized方法,鎖的就是對象本身也就是this
A裏面有一個synchronized修飾的方法
如果多線程調用 【A a = new A(); a.synchronized()(調用synchronized修飾的方法)】
例如:
class Sync {
public synchronized void test() {
System.out.println("test開始..");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("test結束..");
}
}
class MyThread extends Thread {
public void run() {
Sync sync = new Sync();
sync.test();
}
}
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
Thread thread = new MyThread();
thread.start();
}
}
}
每次調用都是一個新的對象,synchronized顯然沒有任何作用,改爲內部synchronized(this),也沒有任何作用
- syschronized(Object.class) 內部
synchronized(Sync.class)實現了全局鎖的效果。
可以訪問該類沒有被修飾的方法
static synchronized方法也相當於全局鎖,相當於鎖住了代碼段 ,鎖定的效果就影響所有靜態的同步方法
③CountDownLunch的使用
初始化一個值
countDownLatch.countDown(); 內部的計數器減1
countDownLatch.await(); 讓當前的線程進行休眠,當計數器爲0時,將被喚醒
常用線程池
spring異步線程池
ThreadPoolTaskExecutor
@Bean
public ThreadPoolTaskExecutor taskExecutor() {
ThreadPoolTaskExecutor threadPool = new ThreadPoolTaskExecutor();
//設置核心線程數
threadPool.setCorePoolSize(10);
//設置最大線程數
threadPool.setMaxPoolSize(50);
//線程池所使用的緩衝隊列
threadPool.setQueueCapacity(200);
//等待任務在關機時完成--表明等待所有線程執行完
threadPool.setWaitForTasksToCompleteOnShutdown(true);
// 等待時間 (默認爲0,此時立即停止),並沒等待xx秒後強制停止
threadPool.setAwaitTerminationSeconds(60);
threadPool.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 初始化線程
threadPool.initialize();
return threadPool;
}
execute() 無返回值
submit() 有返回值
invokeAll() 批量獲取返回值
在獲取返回值的時候,阻塞獲取返回值。