進程和線程的區別:
1.進程有以下幾個特點:
- 獨立性:是系統中獨立存在的實體。有自己的資源和地址空間,沒有進程的允許,其他進程不允許訪問該進程的地址空間。
- 動態性:程序是一個靜態的指令集合,而進程是一個正在系統中活動的指令集合,進程有自己的生命週期和各種不同的狀態
- 併發性:多個進程可以在單個處理器上併發執行而互不影響
2.併發性和並行性的區別:
- 併發性:多個指令在多個處理器上同時執行
- 並行性:同一時刻只能有一條指令執行,而多個進程指令快速輪換執行,看起來就像是多個進程同時執行的樣子
3.線程和進程的區別:
- 線程也叫輕量級進程
- 線程可以有自己的堆棧、程序計數器、局部變量,但不擁有系統資源,與父進程的其他線程共享該進程所擁有的全部資源
- 一個程序運行後至少有一個進程,一個進程可以包括多個線程,但至少有一個線程
4.多線程的優點
- 創建進程需要系統爲它分配系統資源,創建線程的代價小,效率會更高
- 進程直接不能共享內存,線程直接共享非常容易
- Java語言內置了多線程功能的支持,而不只是作爲底層操作系統的調度方式,簡化了多線程變成
線程的創建和啓動:
有以下三種方式:
- 繼承Thread
- 實現Runnable接口
- 實現Callable接口
(1)繼承Thread
// 繼承Thread類
class FirstThread extends Thread{
// 這個是**實例屬性**,不是局部變量
private int i;
@Override
public void run() {
super.run();
for (;i < 100; i++){
Log.e("testthread",getName() +","+ i);
}
}
}
mBntFun1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
for (int i = 0;i < 100;i++){
Log.e("testthread",Thread.currentThread() +","+ i);
if (i == 20){
// 創建並啓動第一個線程
new FirstThread().start();
// 創建並啓動第二線程
new FirstThread().start();
}
}
}
});
說明:
(1)定義一個類繼承Thread,重寫run()方法,裏面代表線程需要完成的任務,run()就是線程執行體
(2)創建Thread子類的實例,即創建了子線程
(3)通過調用start()方法啓動線程
(4)因爲是繼承的Thread,直接用this代表當前線程。getName()返回線程的名字。
(5)通過Thread來創建線程類的時候,多個線程之間無法共享線程類的實例屬性
(2)實現Runnable接口
class SecondRunnable implements Runnable{
private int i;
@Override
public void run() {
for (;i < 100; i++){
Log.e("testthread",Thread.currentThread().getName() +","+ i);
}
}
}
mBntFun2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
for (int i = 0;i < 100;i++){
Log.e("testthread",Thread.currentThread().getName() +","+ i);
if (i == 20){
SecondRunnable sr = new SecondRunnable();
// 創建並啓動第一個線程
new Thread(sr,"thread--1").start();
// 創建並啓動第二線程
new Thread(sr,"thread--2").start();
}
}
}
});
== 說明 ==
(1)創建Runnable的實例,作爲Thread的target,new Thread(target,name)
(2)Runnable裏面的run()還是線程執行體,實際的線程仍然是Thread實例
(3)實現Runnable接口的時候,如果想獲取到當前線程,只能用Thread.currentThread()
(4)採用Runnable創建的多個線程可以共享線程類(實際上是線程的target類)的實體屬性,因爲這種情況下創建的Runnable只是Thread的target,兩個線程可以共享一個target。
使用Callable和Future創建線程
public class ThirdThread implements Callable<Integer>{
private int i = 0;
@Override
public Integer call() throws Exception {
for (;i < 100; i++){
Log.e("testthread",Thread.currentThread().getName() +","+ i);
}
return i;
}
}
mBntFun3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
ThirdThread callable = new ThirdThread();
FutureTask<Integer> future = new FutureTask<Integer>(callable);
for (int i = 0;i < 100;i++){
Log.e("testthread",Thread.currentThread().getName() +","+ i);
if (i == 20){
new Thread(future,"線程1").start();
}
}
try {
Log.e("testthread","返回值:"+future.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
});
說明
(1)創建Callable的實現類,實現run方法,run()仍然是線程執行體
(2)創建Callable的實例,使用FutureTask類來包裝Callable對象,該FutureTask封裝了Callable中call(()的返回值
(3)使用FutureTask對象作爲Thread的target
(4)調用FutureTask對象的get()方法獲得子線程執行結束後的返回值;
補充說明
Future接口:
-
public boolean cancel(boolean mayInterruptIfRunning):
取消FutureTask關聯的Callable任務 -
public V get():
獲得call()的返回值,調用該方法會造成線程阻塞,必須等到子線程結束後纔會得到返回值 -
public V get(long timeout, TimeUnit unit)
超過timeout和Unit指定的時間,還沒有得到返回值,則會拋出 TimeoutException -
public boolean isCancelled()
在Callable任務正常完成前被取消,則返回true -
public boolean isDone()
如果Callable任務已經完成,則返回true