1. 程式人生 > >多執行緒之多視窗賣票&執行緒之間的通訊

多執行緒之多視窗賣票&執行緒之間的通訊

案例一:使用多執行緒完成三個視窗賣票(不能出現重複賣票以及負數票)

賣票程式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();
	}
}
執行結果: