创建单个“火车票类”
package date0804.demo3;
/**
* 票
* @author zzw922cn
*
*/
public final class Ticket {
private final String name;
public Ticket(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
}
火车票DB的构建
采用静态工厂生产火车票的模式:
package date0804.demo3;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.util.ArrayList;
import javax.xml.bind.DatatypeConverter;
public class TicketFactory {
private ArrayList<Ticket> list = new ArrayList<Ticket>();
private String str="seed";
private final int NUMBER_OF_TICKETS=100;
private TicketFactory() {
//产生火车票
for(int count=0;count<NUMBER_OF_TICKETS;count++) {
InputStream inputStream = new ByteArrayInputStream(str.getBytes());
MessageDigest instance;
try {
instance = MessageDigest.getInstance("MD2");
DigestInputStream digestInputStream = new DigestInputStream(inputStream, instance);
while(digestInputStream.read()!=-1)
;
digestInputStream.close();
byte[] digest = instance.digest();
str=DatatypeConverter.printHexBinary(digest);
list.add(new Ticket(str));
}catch(Exception ex) {
ex.printStackTrace();
}
}
}
private static TicketFactory ticketFactory=new TicketFactory();
public static ArrayList<Ticket> getTickets() {
return ticketFactory.list;
}
}
火车票的操作与DB的变更
package date0804.demo3;
/**
* 售票系统
*/
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
/**
* 多线程模拟火车票售票系统
* @author zzw922cn
*
*/
public class TicketOperation {
private ArrayList<Ticket> list;
public TicketOperation(ArrayList<Ticket> list) {
this.list=list;
}
public Map<Integer,Ticket> sell(){
synchronized (this) {
HashMap<Integer, Ticket> hashMap=new HashMap<Integer, Ticket>();
if(list.size()>0) {
Ticket ticket=list.get(0);
list.remove(0);
int size=list.size();
hashMap.put(size, ticket);
return hashMap;
}else {
return null;
}
}
}
}
购票行为线程
package date0804.demo3;
import java.io.File;
/**
* 买票
*/
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class BuyTicketRunnable implements Runnable {
private TicketOperation ticketDb;
private String content;
File file=new File("ticket.log");
public BuyTicketRunnable(TicketOperation ticketDb) {
this.ticketDb = ticketDb;
}
@Override
public void run() {
Map<Integer,Ticket> map=ticketDb.sell();
if(map!=null) {
Set<Entry<Integer, Ticket>> entrySet = map.entrySet();
Iterator<Entry<Integer, Ticket>> iterator2 = entrySet.iterator();
Entry<Integer, Ticket> next = iterator2.next();
int size=next.getKey();
Ticket ticket=next.getValue();
content="Thread "+Thread.currentThread().getId()+"买了一张票:"+ticket.getName()+
"剩余票数为"+size;
}
else {
content="Thread "+Thread.currentThread().getId()+"票已售空";
}
//记录日志
WritingThread writingThread = new WritingThread(file,content);
writingThread.start();
}
}
日志记录
package date0804.demo3;
/**
* 记录日志
*/
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.Date;
public class LoggingFile {
private Writer out;
public LoggingFile(File f) throws IOException {
FileWriter fileWriter = new FileWriter(f,true);
//使用缓冲包装写入器,能够增加效率
this.out = new BufferedWriter(fileWriter);
}
public void writeLogs(String message) throws IOException {
synchronized(out) {
Date d=new Date();
StringBuilder stringBuilder = new StringBuilder(d.toString());
stringBuilder.append('\t');
stringBuilder.append(message);
stringBuilder.append("\r\n");
out.write(stringBuilder.toString());
System.out.println(stringBuilder.toString());
}
}
public void close() throws IOException {
out.flush();
out.close();
}
}
日志的写入线程
package date0804.demo3;
/**
* 日志写入文件
*/
import java.io.File;
import java.io.IOException;
public class WritingThread extends Thread {
private File logFile;
private String content;
public WritingThread(File logFile,String content) {
this.logFile=logFile;
this.content=content;
}
@Override
public void run() {
try {
LoggingFile loggingFile = new LoggingFile(logFile);
loggingFile.writeLogs(content);
loggingFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
测试类
package date0804.demo3;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.concurrent.ExecutionException;
public class Test {
private final static int NUMBER_OF_BUYERS=120;
public static void main(String[] args) throws InterruptedException, IOException, NoSuchAlgorithmException, ExecutionException {
ArrayList<Ticket> list=TicketFactory.getTickets();
TicketOperation ticketOperation = new TicketOperation(list);
BuyTicketRunnable buyTicketThread = new BuyTicketRunnable(ticketOperation);
for(int i=0;i<NUMBER_OF_BUYERS;i++) {
Thread thread= new Thread(buyTicketThread);
thread.start();
}
}
}