1. Thread
public class ThreadTest {
public static void main(String[] args){
new MyThread().start();
new MyThread().start();
}
}
class MyThread extends Thread{
int ticket=3;
@Override
public void run(){
for(int i=0;i<10;i++){
if(ticket>0){
System.out.println("售出車票第" + ticket-- + "張");
}
}
}
}
輸出結果
售出車票第3張
售出車票第3張
售出車票第2張
售出車票第2張
售出車票第1張
售出車票第1張
每個Thread是一個獨立線程,資源不共享
2. Runnable
public class RunnableTest {
public static void main(String[] args){
RunnableDemo runnable=new RunnableDemo();
new Thread(runnable,"售票線程1").start();
new Thread(runnable,"售票線程2").start();
}
}
class RunnableDemo implements Runnable{
private int ticket = 3;
@Override
public void run(){
System.out.println("當前線程名:" + Thread.currentThread().getName());
for (int i = 0; i < 10; i++) {
if(ticket>0) {
System.out.println("售出車票第" + ticket-- + "張");
}
}
}
}
輸出結果
當前線程名:售票線程2
售出車票第3張
售出車票第2張
當前線程名:售票線程1
售出車票第1張
線程的真實執行順序與代碼順序無關
3. Callable
public class CallableTest {
public static void main(String[] args) {
CallableDemo demo=new CallableDemo();
FutureTask<Integer> futureTask = new FutureTask<>(demo);
new Thread(futureTask, "callable線程").start();
try {
System.out.println("返回值:" + futureTask.get());
} catch (Exception e) {
e.printStackTrace();
}
}
}
class CallableDemo implements Callable<Integer>{
@Override
public Integer call() throws Exception{
System.out.println("當前線程名:"+Thread.currentThread().getName());
int i=0;
for (; i < 5; i++) {
System.out.println("i="+i);
}
return i;
}
}
運行結果
當前線程名:callable線程
i=0
i=1
i=2
i=3
i=4
返回值:5
通過futureTask.get()獲取線程返回值
對比
Runnable比Thread有下列優勢
- 避免了Java單繼承的特性
- 增強程序簡裝行,代碼能被多個線程共享,代碼與數據是獨立的
- 適合多個相同程序代碼的線程處理同一資源的情況
Runnable與Callable區別
- Callable.call(),Runnable.run()
- Callable執行後可返回值
- Callable可拋出異常
- 運行Callable任務可以拿到一個Future隊形,表示異步計算的結果。通過Future可瞭解任務執行情況,可取消任務的執行,還可以獲取執行結果
- 加入線程池運行,Runable使用execute,Callable使用submit方法