執行緒的幾種建立方式並實現賣票功能
阿新 • • 發佈:2019-02-03
本篇簡單的講下執行緒的幾種建立方式並相應的實現售票功能
一、執行緒建立
public class ThreadTest { public static void main(String[] args) throws InterruptedException, ExecutionException { //執行緒的三種建立方式 //1繼承thread類 重寫run方法 createThread thread=new createThread(); thread.start(); //2實現Runnable介面 重寫run方法 createThread1 thread1=new createThread1(); Thread thread2=new Thread(thread1); thread2.start(); //3實現callable介面,重寫call方法 createThread2 thred2=new createThread2(); FutureTask<String> ft=new FutureTask<String>(thred2); new Thread(ft).start(); System.out.println("返回值:"+ft.get()); //4利用ExecutorService執行緒池來管理執行緒 ExecutorService threadPool=Executors.newFixedThreadPool(2); threadPool.execute(thread1); } } //繼承thread類 class createThread extends Thread{ @Override public void run() { for(int i=0;i<10;i++){ System.out.println(Thread.currentThread().getName()+" i:"+i); } } } //實現runnable介面 class createThread1 implements Runnable{ @Override public void run() { for(int i=0;i<10;i++){ System.out.println(Thread.currentThread().getName()+" i:"+i); } } } //實現callable介面 class createThread2 implements Callable<String>{ @Override public String call() throws Exception { for(int i=0;i<10;i++){ System.out.println(Thread.currentThread().getName()+" i:"+i); } return "該方法建立執行緒有返回值"; } }
第三種方式是利用了FutureTask類和Callable介面
首先建立Callable介面的實現類,實現call()方法,該方法比run()方法要強大,會有返回值返回。
使用FutureTask類包裝Callable物件,建立thread物件,將FutureTask物件傳給thrad,呼叫start()方法開啟執行緒。呼叫FutureTask物件的get()方法可以獲得執行緒結束後的返回值。
其他三者之間的比較,無非是繼承thread類的,獲取當前執行緒可以直接this.getName(),不能再繼承其他的類了。
而實現介面的方式獲取當前執行緒必須用Thread.currentThread().getName(),還能夠再繼承其他的類。
二、基於上面的三種方式實現賣票功能
描述:有四個視窗在買票,總票數為100,每售出一張,打印出視窗號和票的序號。每個視窗命名"視窗1”到"視窗4"
(1)繼承thread實現
public static void main(String[] args) { ticketsWindow tic1=new ticketsWindow(); tic1.setName("視窗1"); ticketsWindow tic2=new ticketsWindow(); tic2.setName("視窗2"); ticketsWindow tic3=new ticketsWindow(); tic3.setName("視窗3"); ticketsWindow tic4=new ticketsWindow(); tic4.setName("視窗4"); tic1.start(); tic2.start(); tic3.start(); tic4.start(); } } class ticketsWindow extends Thread{ private static int ticket=100; private static Object o=new Object(); public void run(){ while(true){ synchronized (o) { if(ticket>0){ try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } ticket--; System.out.println(getName()+":第"+(100-ticket)+"張票已被售出"); }else{ break; } } } } }
(2)實現Runnable介面
public static void main(String[] args) {
ticketsWindows tkw = new ticketsWindows();
Thread s1 = new Thread(tkw, "視窗1");
Thread s2 = new Thread(tkw, "視窗2");
Thread s3 = new Thread(tkw, "視窗3");
Thread s4 = new Thread(tkw, "視窗4");
s1.start();
s2.start();
s3.start();
s4.start();
}
}
class ticketsWindows implements Runnable {
private static int ticket = 100;
@Override
public void run() {
while (true) {
synchronized (this) {
if (ticket > 0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
--ticket;
System.out.println(Thread.currentThread().getName() + " :第"
+ (100 - ticket) + "張票已售出");
} else {
break;
}
}
}
}
(3)利用ExecutorService執行緒池
public class TicketThread3 {
public static void main(String[] args) {
ExecutorService threadPool = Executors.newFixedThreadPool(4);
Ticket tickT = new Ticket();
for (int i = 1; i < 5; i++) {
Thread thread = new Thread(tickT);
threadPool.execute(thread);
}
}
}
class Ticket implements Runnable {
private static int i = 10;
@Override
public void run() {
while (true) {
synchronized (this) {
if (i > 0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
--i;
System.out.println(Thread.currentThread().getName() + " :第"
+ (10 - i) + "張票已售出");
} else {
break;
}
}
}
}
}
輸出結果: