多執行緒之多視窗賣票&執行緒之間的通訊
阿新 • • 發佈:2019-01-08
案例一:使用多執行緒完成三個視窗賣票(不能出現重複賣票以及負數票)
賣票程式SellTicket 這裡使用Lock類中的方法實現加鎖和釋放鎖!
測試類package cn.itcast.thread2; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class SellTicket implements Runnable { private int tickets = 100; private Lock lock=new ReentrantLock(); private Object obj=new Object(); @Override public void run() { while (true) { lock.lock();//這裡也可以使用synchronized(obj){if中的程式碼} 要使用同一把鎖 if (tickets > 0) { try { Thread.sleep(100);// 休息一會 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "正在賣第" + tickets-- + "張票"); } lock.unlock();//釋放鎖 } } }
案例二:執行緒之間的通訊package cn.itcast.thread2; public class SellTicketTest { public static void main(String[] args) { SellTicket s1=new SellTicket(); Thread t1=new Thread(s1); Thread t2=new Thread(s1); Thread t3=new Thread(s1); t1.setName("視窗一"); t2.setName("視窗二"); t3.setName("視窗三"); t1.start(); t2.start(); t3.start(); } }
執行緒之間的通訊就是對同一個資料的操作:舉例說明-->
如賣包子,如果包子鋪沒有包子就讓生產商產包子,同時顧客等待.如果包子鋪有包子就賣包子,生產商就不能產包子,就等待包子鋪賣完後才能生產包子!因此生產商等待!
程式碼:
學生類Student
package cn.itcast.thread3;
public class Student {
int age;
boolean flag;//預設是沒有資料的false 如果有資料就為true
String name;
}
設定執行緒:
獲取執行緒:package cn.itcast.thread3; /** * 執行緒之間的通訊 * 如果有學生就不set了 * @author Administrator * */ public class SetThread implements Runnable{ public Student s; private int x=0; public SetThread(Student s){ this.s=s; } @Override public void run() { while(true){ synchronized (s) {//把要操作的student物件當成鎖物件 if(s.flag){//判斷有沒有資料 如果有資料了就等著釋放鎖 try { s.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } //沒有資料 就建立資料 if(x%2==0){//是偶數就建立李衛康 s.name="李衛康"; s.age=23; }else{//是奇數就建立韓瑋 s.name="韓瑋"; s.age=22; } x++;//x++ //如果已經設定了資料就更改標記 s.flag=true;//有資料了就等著 因此說更改標記為true s.notify();//喚醒 } } } }
package cn.itcast.thread3;
public class GetThread implements Runnable{
public Student s;
public GetThread(Student s){
this.s=s;
}
@Override
public void run() {
while(true){
synchronized (s) {
if(!s.flag){//如果flag是false說明沒有資料就不獲取資料了就等著
try {
s.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//有資料就列印
System.out.println("學生的姓名和年齡分別是:"+s.name+":"+s.age);
//修改標記
s.flag=false;//沒資料了就等著
//喚醒
s.notify();//
}
}
}
}
測試類:
package cn.itcast.thread3;
public class Test {
public static void main(String[] args) {
//建立資源
Student s=new Student();
//設定和獲取的類
GetThread get=new GetThread(s);
SetThread set=new SetThread(s);
Thread t1=new Thread(get);
Thread t2=new Thread(set);
//啟動執行緒
t1.start();
t2.start();
}
}
執行結果: