Java实现多线程售票
生活随笔
收集整理的這篇文章主要介紹了
Java实现多线程售票
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- Synchronized和Lock的區別是什么?
- 案例一
- 方法一 繼承Thread類
- 方法二 實現Runnable接口
- 案例二
- 方法一 繼承Thread類
- 方法二 實現Runnable接口
- 案例三
- 方法一 繼承Thread類
- 方法二 實現Runnable接口
- 案例四
- 方法一 繼承Thread類
- 方法二 實現Runnable接口
- 案例五
- 方法一 繼承Thread類
- 方法二 實現Runnable接口
- 案例六
- 方法一 繼承Thread類
- 方法二 實現Runnable接口
- 案例七
- 方法一 繼承Thread類
- 方法二 實現Runnable接口
- 案例八
- 方法一 繼承Thread類
- 方法二 實現Runnable接口
- 案例九
- 方法一 繼承Thread類
- 方法二 實現Runnable接口
Synchronized和Lock的區別是什么?
1.synchronized是Java中的關鍵字,是jdk自帶的;Lock是一個接口
2.synchronized在線程執行發生異常時,jvm會讓線程釋放鎖,因此不會導致死鎖現象發生;Lock在finally中必須通過unLock()去釋放鎖,不然容易造成線程死鎖
3.使用synchronized時,如果A線程阻塞,B線程會一直等待,不能夠響應中斷;Lock可以嘗試獲得鎖,線程可以不用一直等待,通過interrupt()方法能夠響應中斷(interrupt無法中斷已經獲取的鎖,只能中斷等待狀態)
4.synchronized無法判斷鎖的狀態;Lock可以知道有沒有成功獲取鎖(可以通過其中的tryLock()等自帶的多個方法去嘗試獲取鎖)
在性能上來說,如果競爭資源不激烈,兩者的性能是差不多的,而當多線程競爭資源非常激烈時,此時Lock的性能要遠遠優于synchronized。具體使用時要根據適當情況選擇。
案例一
方法一 繼承Thread類
package sell;import java.lang.Thread;public class SaleSysTest {public static void main(String[] args) {//創建5個線程,傳入線程名[001]、[002]...并開啟for(int i=1;i<6;i++) {new SaleThread("[00"+i+"]").start();}}}class SaleThread extends Thread{//車票數被共享,所以定義為static,數量為50.private static int ticket=50;//通過鎖來保證線程不會重復訪問private static Object obj=new Object();//有參構造傳入線程名public SaleThread(String name) {// TODO Auto-generated constructor stubsuper(name);}//無參構造傳入線程名public SaleThread() {}//重寫run()方法,將售票動作放入其中public void run() {while(true) {//在鎖外使用sleep(),以便于更好的解決復現問題try {Thread.sleep(100);}catch(InterruptedException e) {e.printStackTrace();}//使用synchronized需要鎖統一資源,不然沒效果,所以將obj初始化為static靜態。//但讓也可以使用字符串 synchronized("lock");lock隨便輸入synchronized(obj) {//還有余票---出票if(ticket>0) {System.out.println(Thread.currentThread().getName()+"號窗口第"+ticket+"票 正在出票...");ticket--;}else {//車票售罄System.out.println("車票已售罄,下次請趁早...");//退出System.exit(0);}}}} }方法二 實現Runnable接口
package sell;import java.text.SimpleDateFormat; import java.util.Date; import java.util.Scanner;class Selldemolist implements Runnable {Scanner in=new Scanner(System.in);int tickets=in.nextInt();private int salenum=0;public void sellTickets() { synchronized (this) {if (tickets > 0) {tickets--;salenum++;System.out.println(Thread.currentThread().getName() + "已經購買編號為"+salenum+"的票");Date date=new Date();SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String time=sdf.format(date);System.out.println("出票時間為:"+time);try {Thread.sleep(500);} catch (InterruptedException e) { e.printStackTrace();}System.out.println("___________________________________");System.out.println(" ");}}}public void run() {while (tickets > 0) {sellTickets();try {Thread.sleep(400);if(tickets==0){System.out.println("非常抱歉,售票已經結束,請明天再來!");System.exit(-1);}} catch (InterruptedException e) {e.printStackTrace();}}}}public class Selldemo1 {public static void main(String[] args) {Selldemolist ticket=new Selldemolist();Thread mary = new Thread(ticket,"瑪麗");Thread jack = new Thread(ticket,"杰克");Thread rose=new Thread(ticket,"柔絲");Thread black=new Thread(ticket,"布萊克");mary.start();jack.start();rose.start();black.start();} }案例二
方法一 繼承Thread類
package Demo;public class Sellticket1 {public static void main(String[] args) {//創建3個線程,并開啟for(int i=1;i<4;i++){new TicketWindow("窗口"+i+":").start();}} }//方法1.繼承Thread類 class TicketWindow extends Thread{private static int ticket = 100;//車票數被共享,所以定義為static private static Object obj = new Object();//通過鎖來保證線程不會重復訪問//有參構造傳入線程名public TicketWindow(String name) {super(name);}public TicketWindow() {}//重寫run()方法,將售票動作放入其中public void run() {while (true) {//在鎖外使用sleep( );以便于更好的解決復現問題try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}//也可以使用字符串 synchronized("lock");lock隨便輸入synchronized (obj) { if (ticket > 0) {System.out.println(Thread.currentThread().getName() + "第-- "+ ticket + " --票正在出票...");ticket--;} else { System.out.println("票已售完 下次再見!!");System.exit(0);}}}} }方法二 實現Runnable接口
package Demo;public class Sellticket2 {public static void main(String[] args) {Windows sc = new Windows();//創建3個線程,并開啟for(int i=1;i<4;i++){new Thread(sc,"窗口"+i).start();}} }//方法2.實現Runnable接口 class Windows implements Runnable{private int ticket = 100; private Object obj = new Object(); //定義一個線程同步對象public void run() { while(true){try {Thread.sleep(50);} catch (InterruptedException e) {e.printStackTrace();}//同步鎖synchronized(obj){if(ticket > 0){System.out.println(Thread.currentThread().getName()+" 售出第-- "+ticket +" --張票");ticket--;}else{System.out.println("票已售完 下次再見!!");System.exit(0);}}} } }案例三
方法一 繼承Thread類
package xiancheng;import java.util.Scanner;class thread extends Thread {public static int num, num1;public static Object obj = new Object();public int i = 1;public thread(String name) {super(name);}public thread() {}@Overridepublic void run() {// TODO 自動生成的方法存根while(true) {try {Thread.sleep(500);} catch (InterruptedException e) {// TODO 自動生成的 catch 塊e.printStackTrace();}synchronized(obj) {if(num > 0) {System.out.println("售票點:" + Thread.currentThread().getName() + " 當前賣出票號:" + (num1 - num + 1) );num--;} else {System.out.println("已賣完");System.exit(0);}}}}public void getChePiao(int chePiao) {num = chePiao; num1 = chePiao;} }public class DoThread {public static void main(String[] args) {// TODO 自動生成的方法存根int i;Scanner scanner = new Scanner(System.in);System.out.print("請問要賣多少張票:");new thread().getChePiao(scanner.nextInt());for(i = 1 ; i <= 4 ; i++) {new thread("" + i).start();}}}方法二 實現Runnable接口
package xiancheng;import java.util.Scanner;class Runn implements Runnable {public int num, i = 1, num1;@Overridepublic void run() {// TODO 自動生成的方法存根while(true) {try {Thread.sleep(500);} catch (InterruptedException e) {// TODO 自動生成的 catch 塊e.printStackTrace();}doRun();if(num <= 0) {System.exit(0);;}}}public synchronized void doRun() {if(i > 0 && i <= num1) {System.out.println("售票點:" + Thread.currentThread().getName() + " 當前賣出票號:" + i);i++;num--;} else if(num <= 0) {System.out.println("已賣完");System.exit(0);}}public void getChePiao() {Scanner scanner = new Scanner(System.in);System.out.print("請問要賣多少張票:");num = scanner.nextInt(); num1 = num;} }public class DoRunnable {public static void main(String[] args) {// TODO 自動生成的方法存根int i;Runn runn = new Runn();runn.getChePiao();for(i = 1 ; i <= 4 ; i++) {new Thread(runn, "" + i).start();}} }案例四
方法一 繼承Thread類
package one;import java.util.Scanner;public class Sale {private static int ticket,temp;public static void main(String [] args) {System.out.println("請輸入您發放的票數:");Scanner in = new Scanner(System.in);String x = in.nextLine();ticket = Integer.parseInt(x);temp = ticket; for(int i=1;i<6;i++) {new sell1(" ["+i+"]",temp).start();}} }class sell1 extends Thread { private static int ticket,temp1;private static Object obj = new Object();public sell1() {}public sell1(String name,int temp) {super (name);ticket = temp;}@Overridepublic void run() {temp1 = ticket;while (true) {try {Thread.sleep(100);}catch(InterruptedException e) {e.printStackTrace();}synchronized (obj) {if(ticket>0) {int a = temp1-ticket+1;System.out.println("售票點:"+Thread.currentThread().getName()+ "\t當前票號: "+a);ticket--;}else {System.out.println("車票已經售完,下次請趁早...");System.exit(0);}}}} }方法二 實現Runnable接口
package two;import java.util.Scanner;public class Sale2 {public static void main(String [] args) {int ticket1;System.out.println("請輸入您發放的票數:");Scanner in = new Scanner(System.in);String x = in.nextLine();ticket1 = Integer.parseInt(x);sell s = new sell(ticket1); for(int i=1;i<6;i++) {new Thread(s,"["+i+"]").start();}} }class sell implements Runnable{ private static int ticket,temp1;private static Object obj = new Object();public sell() {}public sell(int ticket1) {ticket = ticket1;}@Overridepublic void run() {temp1 = ticket; while (true) {try {Thread.sleep(100);}catch(InterruptedException e) {e.printStackTrace();}synchronized (obj) {if(ticket>0) {int a = temp1-ticket+1;System.out.println("售票點:"+Thread.currentThread().getName()+ "\t當前票號: "+a);ticket--;}else {System.out.println("車票已經售完,下次請趁早...");System.exit(0);}}}} }案例五
方法一 繼承Thread類
package eclipse;public class Ticket1 {public static void main(String[] args) {// TODO Auto-generated method stub//首先創建5個線程,傳入線程名:如[001]、[002]等,并將其開啟。int i;for(i=1;i<+5;i++) {new SaleThread("[00"+i+"]").start();}}} class SaleThread extends Thread{//由于車票數要對公眾共享,所以要定義為靜態成員變量,數量定為100.private static int ticket=100;//通過鎖來保證線程都不會被重復訪問.private static Object obj=new Object();//把有參構造傳入線程名public SaleThread(String name) {super(name);}public SaleThread(){}//重新寫入run()方法,將售票動作放入其中; @Override public void run() {while(true) {//要在鎖外使用sleep(); try {Thread.sleep(100);}catch(InterruptedException e) {e.printStackTrace();}//使用synchronized需要統一資源,不然沒效果,所以將obj初始化為static靜態.//但讓也可以使用字符串 synchronized("lock");lock隨便輸入 synchronized(obj) {//還有余票——————出票if(ticket>0) {System.out.println(Thread.currentThread().getName()+"號窗口正在出票...票號:"+ticket);ticket--;}else {//利用if,else語句來看看車票售出的情況,如果售出完成,則執行else下面的語句。System.out.println("車票已經售完,下次請趁早買票!");System.exit(0);} } } } }方法二 實現Runnable接口
package eclipse;public class Ticket2 {public static void main(String[] args) {// TODO Auto-generated method stub //首先得到對象SaleSys a =new SaleSys();//然后把對象放入線程中for(int i=1;i<6;i++) {new Thread(a,"[00"+i+"]").start();}}}class SaleSys implements Runnable{//定義票的總數private int ticket = 100;//定義一個線程同步的對象private Object obj=new Object();@Overridepublic void run() {while(true) {try {Thread.sleep(50);}catch(InterruptedException e) {e.printStackTrace();}//同步鎖synchronized(obj) {if(ticket>0) {System.out.println(Thread.currentThread().getName()+"號窗口正在售票...票號:"+ticket);ticket--;}else {System.out.println("票已售完,請下次再來吧!");System.exit(0);}}}} }案例六
方法一 繼承Thread類
package com.hym.Threaded;public class Sale_Thread{public static void main(String[] args) {// TODO Auto-generated method stub//創建五個窗口(線程)for(int i = 1;i < 6;i++) {new SaleThread("[0" + i + "]").start();}} } class SaleThread extends Thread{//車票數為共享變量,靜態變量定義用static,數量為100private static int tickets = 100;//通過鎖使這個線程不會被重復訪問private static Object obj = new Object();public SaleThread(String name) {super(name);}public SaleThread() {}//重寫run方法 @Override public void run() {while(true) {try {Thread.sleep(200);}catch(InterruptedException e){e.printStackTrace();}//將obj初始化為static靜態synchronized (obj) {if(tickets > 0) {System.out.println(Thread.currentThread().getName() + "號窗口第" + tickets-- + "票正在出票...");}else {//車票售完System.out.println("車票已售罄。");System.exit(0);}}} }}方法二 實現Runnable接口
package com.hym.Threaded;public class Test2 {public static void main(String[] args) {// TODO Auto-generated method stubSaleSys s = new SaleSys();//創建五個窗口(線程)for(int i = 1;i < 6;i++) {new SaleThread("[0" + i + "]").start();}}} class SaleSys implements Runnable{//車票數為共享變量,靜態變量定義用static,數量為100private static int tickets = 100;//通過鎖使這個線程不會被重復訪問private static Object obj = new Object();@Overridepublic void run() {// TODO Auto-generated method stubwhile(true) {try {Thread.sleep(200);}catch(InterruptedException e){e.printStackTrace();}//將obj初始化為static靜態synchronized (obj) {if(tickets > 0) {System.out.println(Thread.currentThread().getName() + "號窗口第" + tickets-- + "票正在出票...");}else {//車票售完System.out.println("車票已售罄。");System.exit(0);}}}} }案例七
方法一 繼承Thread類
package 售票;public class duo2 {public static void main(String[] args) {for(int i=1; i<4; i++){chuangkou2 sp = new chuangkou2();sp.setName(i+"號窗口");sp.start();}}} class chuangkou2 extends Thread{private int tickets = 10;//車票總量public void run(){while(true){if(tickets>0){System.out.println(Thread.currentThread().getName() + "準備售票"); tickets--; System.out.println(Thread.currentThread().getName() + "賣出一張,剩余票數:" + tickets + "張");try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}else{System.out.println(Thread.currentThread().getName() + "余票不足,停止售票!");break;}}} }方法二 實現Runnable接口
package 售票;public class duo{public static void main(String[] args) {chuangkou sp = new chuangkou();for(int i=1; i<4; i++){Thread t = new Thread(sp, i +"號窗口");t.start();} }} class chuangkou implements Runnable{private int tickets = 10;public void run(){while(true){if(tickets>0){shoupiao();}else{System.out.println(Thread.currentThread().getName() + "余票不足,停止售票!");break;}}}public synchronized void shoupiao(){if(tickets>0){System.out.println(Thread.currentThread().getName() + "準備售票"); tickets--; System.out.println(Thread.currentThread().getName() + "賣出一張,剩余票數:" + tickets + "張");try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}}} }案例八
方法一 繼承Thread類
package Thread;import java.util.Calendar;import javax.xml.crypto.Data;import java.util.*; class sale_Thread extends Thread {private static volatile int tickets=2000;public synchronized void run(){while(tickets>0){use();}}private synchronized static void use(){if(tickets>0){System.out.println(Thread.currentThread().getName() +"售出第"+tickets--+"張票");} // try { // Thread.sleep(200); // } catch (InterruptedException e) { // // TODO 自動生成的 catch 塊 // e.printStackTrace(); // }}public static String getWeekOfDate(Date date) { String[] weekDays = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" }; Calendar cal = Calendar.getInstance(); cal.setTime(date); int w = cal.get(Calendar.DAY_OF_WEEK) - 1; if (w < 0) w = 0; return weekDays[w]; }public static void main(String[] args) {Date date=new Date();String w=getWeekOfDate(date);System.out.println(w);String u1="星期五",u2="星期六";if(w.equals(u1)||w.equals(u2)){System.out.println("雙休日期間,不予辦理業務");}else{sale_Thread s1=new sale_Thread();sale_Thread s2=new sale_Thread();sale_Thread s3=new sale_Thread();sale_Thread s4=new sale_Thread();sale_Thread s5=new sale_Thread();Thread t1=new Thread(s1,"售票窗口1");Thread t2=new Thread(s2,"售票窗口2");Thread t3=new Thread(s3,"售票窗口3");Thread t4=new Thread(s4,"售票窗口4");Thread t5=new Thread(s5,"售票窗口5");t1.start();t2.start();t3.start();t4.start();t5.start();}} }方法二 實現Runnable接口
package Runable;public class 售票系統2 {public static int tickets=1000;protected synchronized static void use(){if(tickets>0){System.out.println(Thread.currentThread().getName() +"售出第"+tickets--+"張票");} // try { // Thread.sleep(200); // } catch (InterruptedException e) { // // TODO 自動生成的 catch 塊 // e.printStackTrace(); // }}public static void main(String[] args) {Runner1 runner1 = new Runner1(); Runner2 runner2 = new Runner2(); Runner3 runner3 = new Runner3(); Thread thread1 = new Thread(runner1,"售票窗口1"); Thread thread2 = new Thread(runner2,"售票窗口2"); Thread thread3 = new Thread(runner3,"售票窗口3"); thread1.start(); thread2.start(); thread3.start();} } class Runner1 extends 售票系統2 implements Runnable { public void run() { while(tickets>0)use();} } class Runner2 extends 售票系統2 implements Runnable { // 實現了Runnable接口,jdk就知道這個類是一個線程 public void run() {while(tickets>0)use();} }class Runner3 extends 售票系統2 implements Runnable { // 實現了Runnable接口,jdk就知道這個類是一個線程 public void run() { while(tickets>0)use();} }案例九
方法一 繼承Thread類
package Thticket; /** 繼承Thread類方法售票*/ public class MyThread {public static void main(String[] args) {System.out.println("我是實現系統一");for(int i=1;i<6;i++) {new saleMyThread("第"+i+"窗口 ").start();}} }class saleMyThread extends Thread{private static int tic=100;//創建鎖private static Object obj = new Object();//有參構造傳入線程名public saleMyThread(String name) {super(name);}public saleMyThread() {}@Overridepublic void run() {// TODO Auto-generated method stubwhile (true) {try {//0.1秒Thread.sleep(100);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}//同步鎖synchronized (obj) {if (tic > 0) {System.out.println(Thread.currentThread().getName() + "售出第"+ tic + "票");tic--;}else {//車票售完System.out.println("車票已售完,下次請趁早...");System.exit(0);}}}}}方法二 實現Runnable接口
package Runticket; /** 實現Runnable接口來售票*/ public class MyRunnable {public static void main(String[] args) {System.out.println("我是實現系統二");//得到對象saleMyRunnable mr=new saleMyRunnable();for(int i=1;i<6;i++){new Thread(mr,"第"+i+"窗口 ").start();}} } class saleMyRunnable implements Runnable{//定義票的總數private int tic = 100;//定義一個線程同步對象private Object obj = new Object();@Overridepublic void run() {// TODO Auto-generated method stubwhile(true) {try {//0.1秒Thread.sleep(100);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}//同步鎖synchronized(obj) {if(tic > 0){System.out.println(Thread.currentThread().getName()+" 售出第 "+tic +" 張票");tic--;}else{System.out.println("票已售完,請下次再來!");System.exit(0);}}}}}總結
以上是生活随笔為你收集整理的Java实现多线程售票的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 6月30日航班号HO1695什么时间到成
- 下一篇: Javaweb MVC设计模式、Modl