多線程售票


//測試 多線程售票
//1, 需求: 設計4個售票窗口,總計售票100張。
public class C1 {
public static void main(String[] args) {
//TODO 問題1 : 總共要賣100張,如今賣了400張,爲何??
// 緣由是:int tickets=100;是成員變量,是每一個對象初始化都要存儲的,四個對象存了四份.
// 怎麼解決 --想辦法讓成員變量變成 多個對象間共享的資源,保證全局惟一
MyTickets t = new MyTickets();
MyTickets t2 = new MyTickets();
MyTickets t3 = new MyTickets();
MyTickets t4 = new MyTickets();

t.start();
t2.start();
t3.start();
t4.start();
}
}
//方式1:: extends Thread
class MyTickets extends Thread{
//TODO 問題1 :加上static 把票變成共享資源,而不是人手一份
static int tickets = 100 ;//定義變量,記錄票數
//準備賣票,,把業務放入重寫的run()
@Override
public void run(){
while(true){
if(tickets >0){
//TODO 考驗,多線程編程中的數據到底安全不???--sleep()
try{
//TODO 問題2: 重賣--出現同一張票賣給了多我的
//TODO 問題3: 超賣--賣出了0 -1 -2號票
//TODO 緣由???
Thread.sleep(10);
}catch (InterruptedException e){
e.printStackTrace();
}

System.out.println(super.getName()+"--"+tickets--);
}else{
break;//專門用來結束 死循環 !!
}
}

}
}


//方式2:: implements Runnable
class Ticket implements Runnable{
int ticket = 100;
@Override
public void run() {
while (true){
if(ticket>0){
try {
//TODO 問題2: 重賣--出現同一張票賣給了多我的
//TODO 問題3: 超賣--賣出了0 -1 -2號票
//TODO 緣由???
//重賣的緣由:tickets=80 ,t1 t2 t3 t4 都開始準備賣票 ,
//超賣的緣由:tickets=1 ,t1 t2 t3 t4 都開始準備賣票 ,
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
//超賣的緣由:
//假設t1先醒,開始賣票,執行tickets--,輸出1,自減變成0
//假設t2醒了,開始賣票,執行tickets--,輸出0,自減變成-1
//假設t3醒了,開始賣票,執行tickets--,輸出-1,自減變成-2
//假設t4醒了,開始賣票,執行tickets--,輸出-2,自減變成-3

//重賣的緣由:
//假設t1先醒,開始賣票,執行tickets--,輸出80 沒來得及變
//假設t2醒了,開始賣票,執行tickets--,輸出80 沒來得及變
//假設t3醒了,開始賣票,執行tickets--,輸出80 自減變成79
//假設t4醒了,開始賣票,執行tickets--,輸出79....
System.out.println(Thread.currentThread().getName()+"--"+ticket--);
}else {
break;
}
}
}
}


用同步鎖改進上面程序
public class C2 {
public static void main(String[] args) {
Ticket target = new Ticket();
Thread t = new Thread(target);
Thread t2 = new Thread(target);
Thread t3 = new Thread(target);
Thread t4 = new Thread(target);

t.start();
t2.start();
t3.start();
t4.start();
}
}

同步速方式2:: implements Runnable
class Ticket implements Runnable{
int ticket = 100;
Object o = new Object();
String s ="13";
@Override
//TODO 1,如今因爲多線程 中,,對於共享資源進行了搶的操做,因此共享資源不安全
//能夠使用鎖 來保證安全,可是犧牲性能.synchronized表示鎖
//鎖能夠用在方法上也能夠用在代碼塊上.
//同步方法 synchronized public void run() {
//同步代碼塊 -- synchronized(鎖對象){有問題代碼}
public void run() {
while (true){
//TODO 2,同步代碼塊:須要考慮兩個問題
//1,鎖的位置(合理位置,從開始用到用完結束) 2,鎖對象(能夠任務,但必須是同一個對象)
//synchronized(new Object()){//四個線程new了4把鎖,不是同一個鎖對象,錯的
//synchronized(o){//同一個鎖對象,OK
//synchronized(s){//同一個鎖對象,OK
synchronized (this) {
if (ticket > 0) {
try {

Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "--" + ticket--);
} else {
break;
}
}
}
}
}public class C1 {
    public static void main(String[] args) {
//TODO 問題1 : 總共要賣100張,如今賣了400張,爲何??
// 緣由是:int tickets=100;是成員變量,是每一個對象初始化都要存儲的,四個對象存了四份.
// 怎麼解決 --想辦法讓成員變量變成 多個對象間共享的資源,保證全局惟一
MyTickets t = new MyTickets();
MyTickets t2 = new MyTickets();
MyTickets t3 = new MyTickets();
MyTickets t4 = new MyTickets();

t.start();
t2.start();
t3.start();
t4.start();
}
}


同步鎖改進方式1:: extends Thread
class MyTickets extends Thread{
//TODO 問題1 :加上static 把票變成共享資源,而不是人手一份
static int tickets = 100 ;//定義變量,記錄票數
//準備賣票,,把業務放入重寫的run()
@Override
//TODO 3,方法被同步後,會自動分配鎖對象.普通方法的鎖對象默認是this
//靜態方法的鎖對象纔是 類名.class
// synchronized public void run() {
public void run(){
while(true){
//TODO 1,鎖對象怎麼分配 -- 看你的共享資源是普通仍是靜態的
//TODO 2,靜態資源的 鎖對象 必須是類名.class synchronized (MyTickets.class) { if (tickets > 0) { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(super.getName() + "--" + tickets--); } else { break;//專門用來結束 死循環 !! } } } }}
相關文章
相關標籤/搜索