# 1. 回顧 > 1. java實現多線程: [1]繼承Thread類並重寫run方法 [2]實現Runnable介面 > > 2. 線程Thread中常用的方法: setName(): Thread.currentThread().getName(): > > static void sle ...
1. 回顧
java實現多線程: [1]繼承Thread類並重寫run方法 [2]實現Runnable介面
線程Thread中常用的方法: setName(): Thread.currentThread().getName():
static void sleep(); static void yield(): join(): setDeamon()設置後臺線程
- 線程安全問題: ---當多個線程共用同一個資源時,對該資源的操作就會出現線程安全問題。
- 手動鎖 Lock它是一個介面--lock() unlock() <finally中>
- 自動鎖synchronized
2. 正文
- 什麼是死鎖
- 線程都有哪些狀態?
- 線程通信( 瞭解 wait 和sleep的區別)
- 線程池。
3. 什麼是死鎖
//死鎖小案例
import java.util.concurrent.locks.ReentrantLock;
public class ccc {
public static Object lock = new Object();
public static Object lock2 = new Object();
}
public class eee extends Thread {
@Override
public void run() {
synchronized (ccc.lock){
System.out.println("aaa");
synchronized (ccc.lock2){
System.out.println("bbb");
}
}
}}
public class fff extends Thread{
public void run(){
synchronized (ccc.lock2){
System.out.println("fff");
synchronized (ccc.lock){
System.out.println("e");
}
}
}
}
public class ddd {
public static void main(String[] args) throws InterruptedException {
eee eee = new eee();
fff fff = new fff();
eee.start();
Thread.sleep(100);
fff.start();
}
}
如何解決死鎖: (1) 減少同步代碼塊的嵌套。 (2)設置鎖的超時時間。(3)可以使用安全類-jdk提高的安全類。
4. 線程通信
notify():喚醒。
sleep和wait方法的區別?
(1) 來自不同的類: sleep來自於Thread, wait來自Object類。
(2) 是否釋放鎖資源: sleep不會釋放鎖資源。wait會釋放鎖資源。
(3) 用法: sleep時間到了自然會醒,而wait需要調用notify或notifyAll()方法喚醒。
notify和notifyAll()方法的區別?
1.notify隨機喚醒等待隊列中一個線程,而notifyAll會喚醒等待隊列中所有的線程。
5. 線程的狀態
NEW:新建狀態 RUNNABLE: start()就緒狀態-時間片-運行狀態. 統稱為RUNNABLE BLOCKED: 堵塞狀態。加鎖時就如該狀態 WAITING: 無期等待: 調用wait方法時會進入該狀態 TIMED_WAITING: 有期等待---當調用sleep方法時就會進入該狀態 TERMINATED: 終止狀態。線程的任務代碼執行完畢或出現異常。
線程的狀態之間可以通過調用相應的方法,進行轉換。
6. 線程池
線程池的原理:
線程池的創建
package demo08;
import java.util.concurrent.*;
/*
Executor: 它是線程池的根介面:
void execute(Runnable command):執行Runnable類型的任務。
ExecutorService: 它是Executor的子介面。---
void shutdown():關閉線程池。需要等任務執行完畢。
shutdownNow(); 立即關閉線程池。 不在接受新的任務。
isShutdown(): 判斷是否執行了關閉。
isTerminated(): 判斷線程池是否終止。表示線程池中的任務都執行完畢,並且線程池關閉了
submit(Callable<T> task);提交任務,可以提交Callable
submit(Runnable task): 提交任務,可以提交Runnable任務
Executors: 它是線程池的工具類,該類提供了創建線程池的一些靜態方法
*/
public class Test {
public static void main(String[] args) {
//1.創建一個固定長度的線程池。
// ExecutorService executorService = Executors.newFixedThreadPool(5);
//2. 單一線程池。
// ExecutorService executorService = Executors.newSingleThreadExecutor();
//3. 可變線程池--緩存線程池
// ExecutorService executorService = Executors.newCachedThreadPool();
//4. 延遲線程池。
// ScheduledExecutorService executorService = Executors.newScheduledThreadPool(5);
// for(int i=0;i<100;i++) {
// executorService.submit(new Runnable() {
// public void run() {
// System.out.println(Thread.currentThread().getName() + "~~~~~~~~~~~~~~~~~~~");
// }
// });
//// executorService.schedule(new Runnable() {
//// public void run() {
//// System.out.println(Thread.currentThread().getName() + "~~~~~~~~~~~~~~~~~~~");
//// }
//// },10, TimeUnit.SECONDS);
// }
// executorService.shutdown();
//上面通過Executors工具類創建線程池,但是阿裡巴巴不建議使用。阿裡建議使用原生的模式創建線程池。
/*
int corePoolSize,核心線程的個數
int maximumPoolSize,最多的線程個數
long keepAliveTime, 線程空閑時間。
TimeUnit unit, 空閑的單位
BlockingQueue<Runnable> workQueue:等待隊列
*/
BlockingQueue<Runnable> workQueue=new ArrayBlockingQueue(5);//最多5等待的任務
ThreadPoolExecutor executor=new ThreadPoolExecutor(5,10,10,TimeUnit.SECONDS,workQueue);
//靈活:
for(int i=0;i<25;i++){
executor.submit(new Runnable() {
public void run() {
System.out.println(Thread.currentThread().getName()+"~~~~~~~~~~~~~~~");
}
});
}
}
}
7. Callable創建線程
package demo09;
import demo03.My;
import java.util.concurrent.*;
public class Test {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// MyCallable myCallable=new MyCallable();
// FutureTask<Integer> task=new FutureTask<Integer>(myCallable);//把線程任務封裝到該類中,該類可以獲取線程任務執行後的結果.
// Thread t=new Thread(task);
// t.start();
//
// System.out.println(task.get());
//發現線程執行非常麻煩。都使用線程池來執行任務。---不要自己創建線程對象,而是使用線程池中的對象
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future<Integer> submit =executorService.submit(new MyCallable());
System.out.println(submit.get());
}
}
class MyCallable implements Callable<Integer>{
//線程任務:
public Integer call() throws Exception {
int sum=0;
for(int i=0;i<=10;i++){
sum+=i;
}
return sum;
}
}
class MyRunnable implements Runnable{
public void run() {
}
}
本文來自博客園,作者:知行合二為一,轉載請註明原文鏈接:https://www.cnblogs.com/226zjw/p/17632471.html