Java多线程实现方式主要有四种:
1.继承Thread类
2.实现Runnable接口
3.实现Callable接口通过FutureTask包装器来创建Thread线程
4.使用ExecutorService、Callable、Future实现有返回结果的多线程。
前两种方式线程执行完后都没有返回值,后两种是带返回值的。
前三种实现方式的比较:
(1)线程的start()直接调用的是FutureTask这个类的run方法,而 Callable 的call方法是在run方法内部调用的,因此可以得出extends Thread 和 implements Runnable的run方法是由线程直接调用的,是异步执行的,而call方法是被future调用的,不是异步执行的。
(2)实现Callable接口可以有返回值和抛出异常
我们以前公司做的一个项目,其中网络购票系统就有用多线程实现的。
下面这个是测试类,用于设定参数和开始线程,没什么好说的。(知识点:创建线程对象,线程开启)
package com.thread.movticket;
* 电影票系统线程测试
* 使用方法:sleep,synchronic,join,wait,notify,start,setpriority,yield
* 业务功能:
* vip购票通道购票,平民购票(join,wait,notify)
*/
public class MovieTest {
public static void main(String[] args){
//电影票数
int ticketAmount = 1000;
//根据票数创建电影售票系统
MovieSystem movieSystem = new MovieSystem(ticketAmount);
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
//开启三个窗口买票,两个平民,一个vip
SaleTicket saleTicketA =new SaleTicket(movieSystem,0,ticketAmount);//电影系统对象,vip等级,票数
SaleTicket saleTicketB =new SaleTicket(movieSystem,0,ticketAmount);
SaleTicket vipSaleTicket = new SaleTicket(movieSystem,1,ticketAmount);
System.out.println("******鹅厂电影院开业*****");
Thread t1 = new Thread(saleTicketA,"窗口A");
Thread t2 = new Thread(saleTicketA,"窗口B");
Thread t3 = new Thread(saleTicketA,"Vip窗口");
t1.start();
t2.start();
t3.start();
}
}
下面是主类(知识点:sleep())
package com.thread.movticket;
public class MovieSystem {
//电影票.电影票总数
private int ticketAmount;
private int[] ticket;
public MovieSystem(int ticketAmount) {
//实例化票数创建数组
this.ticketAmount = ticketAmount;
ticket = new int[ticketAmount];
//给电影票以座位号划分()
for (int i=0;i<this.ticketAmount;i++) {
ticket[i] = i+1;
}
}
/*
* 卖票方法
* 当票数大于0才售票,ticketAmount-1是因为票数比数组下标大1,否则告诉返回-1————“没票啦~~”
* 每售出一张票,票数减一,当前线程休眠400ms代表系统在处理信息(其实是为了让我们更好地观察输出结果)
* 结果返回电影票数(也是座位号,原谅我偷懒)
*/
public int saleTicket(){
if (ticketAmount>0) {
if (ticket[ticketAmount-1] > 0) {
ticketAmount--;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
return ticketAmount+1;
}
}
return -1;//没票
}
}
然后是线程类(知识点:①keepRunning停止线程②setPriority()设置线程优先级③synchronize(object o)线程的同步锁,个人感觉对象o没什么用,写上就可以了
-
package com.thread.movticket; -
public class SaleTicket extends Thread{ -
//共享电影系统,创建锁对象,创建显性对象 -
private MovieSystem movieSystem; -
Object object = new Object(); -
boolean KeepRunning = true; -
// private int ticketAmount; -
// int[] seat ; -
//共享电影院系统和票数,设置vip等级 -
public SaleTicket(MovieSystem movieSystem,int viplever,int ticketAmount) { -
this.movieSystem = movieSystem; -
//根据vip等级设置快慢,目前只有普通和vip1级 -
if (viplever == 0) { -
Thread.currentThread().setPriority(MIN_PRIORITY); -
}else if (viplever == 1) { -
Thread.currentThread().setPriority(MAX_PRIORITY); -
} -
} -
public void run() { -
while(KeepRunning){ -
//储存电影系统返回的电影票数量(座位号)并且用synchronize防止被多个线程读取同一个座位号 -
int num; -
synchronized(object){ -
num = movieSystem.saleTicket(); -
if (num > 0) { -
System.out.println(Thread.currentThread().getName()+":卖出"+num+"号座位"); -
System.out.println("还剩"+(num-1)+"张票"); -
}else if (num == -1) { -
System.out.println(Thread.currentThread().getName()+"."+"没票了~~"); -
KeepRunning = false; -
} -
} -
} -
} -
}
本文介绍了一种基于Java多线程技术实现的网络购票系统。系统采用四种多线程实现方式之一,通过模拟不同优先级的售票窗口,演示了线程间的同步与竞争。文章详细展示了代码实现,包括线程的创建、启动、优先级设置及同步锁的使用。
1293

被折叠的 条评论
为什么被折叠?



