您的位置:首页 > 其它

mini售票系统之创建线程的三种方式

2016-02-15 00:16 381 查看

场景

学习多线程编程,写 一个mini售票系统

问题

怎么创建线程,如何模拟售票窗口

实验

模拟3个窗口卖10张票,代码如下:

/**
* Project Name:thinkinginjava
* File Name:ThreadCallable.java
* Package Name:com.sourcecode.java.thread
* Date:2016年2月14日下午10:25:25
* Copyright (c) 2016, 282009375@qq.com All Rights Reserved.
*
*/
package com.sourcecode.java.thread;

import java.util.Date;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
* ClassName: ThreadCallable <br/>
* Function: TODO mini 售票系统 <br/>
* Reason: TODO 学习有返回的线程创建方式<br/>
* date: 2016年2月14日 下午10:25:25 <br/>
*
* @author Administrator
* @version 1.0
* @since JDK 1.6
*/
public class ThreadCallable implements Callable<Object>
{
/*
* 线程数-模拟售票窗口
*/
public static int NUM_ThREADS = 3;

/*
* 总票数
*/
public static int TOTAL_TICKETS = 10;

/*
* 总票数
*/
private int ticket;

/**
* Creates a new instance of ThreadCallable.
*
* @param ticket
*            总票数
*/
public ThreadCallable(int ticket)
{
this.ticket = ticket;
}

/**
* TODO 买票 -有返回的线程执行
*
* @see java.util.concurrent.Callable#call()
*/
@Override
public Object call() throws Exception
{
Date end = null;
Date begin = new Date();
while (true)
{
if (ticket > 0)
{
System.out.println("[Window " + Thread.currentThread().getId() + "] is sailing tiket " + ticket--);
Thread.sleep(10);
} else
{
end = new Date();
break;
}
}
long millisTotal = end.getTime() - begin.getTime();

return TOTAL_TICKETS + " tikcets sold in " + millisTotal + " miliseconds.";
}

/**
* TODO 测试.<br/>
*
* @author Administrator
* @param args
* @since JDK 1.6
*/
public static void main(String[] args)
{
//构造一个固定大小的线程池
ExecutorService poor = Executors.newFixedThreadPool(NUM_ThREADS);

//执行结果封装在Future(这名字取得相当有水准啊,大赞)中:
Future<Object> future = poor.submit(new ThreadCallable(TOTAL_TICKETS));
try
{
//是滴,通过get()就能拿到执行结果
System.out.println(future.get().toString());
} catch (Exception e)
{
System.out.println("Sorry,system busy, please try again later!");
}

//释放池资源
poor.shutdown();
}
}

/**
* Project Name:thinkinginjava
* File Name:ThreadRunnable.java
* Package Name:com.sourcecode.java.thread
* Date:2016年2月14日下午11:11:06
* Copyright (c) 2016, 282009375@qq.com All Rights Reserved.
*
*/
package com.sourcecode.java.thread;

import java.util.Date;

/**
* ClassName: ThreadRunnable <br/>
* Function: 模拟3个窗口共卖10张票  <br/>
* Reason: 通过案例学习多线程3种创建方式的差异  <br/>
* date: 2016年2月14日 下午11:11:06 <br/>
*
* @author Administrator
* @version
* @since JDK 1.6
*/
public class ThreadRunnable
{
/*
* 总票数
*/
public static int TOTAL_TICKETS = 10;

public static void main(String[] args)
{
/*
* extends实现方式无法模拟:多线程处理同一资源(即3个窗口买10张票)
*/
//		ThreadExtends sellerExt = new ThreadExtends(TOTAL_TICKETS);
//		Date begin = new Date();
//		sellerExt.start();
//		Date end = new Date();
//		long millisTotal = end.getTime()-begin.getTime();
//		System.out.println(TOTAL_TICKETS + " tikcets sold in " + millisTotal + " miliseconds.");

//下面的做法实际上实现的是3个窗口卖 30 张票
//		ThreadExtends sellerExt1 = new ThreadExtends();
//		ThreadExtends sellerExt2 = new ThreadExtends();
//		ThreadExtends sellerExt3 = new ThreadExtends();
//		sellerExt1.start();
//		sellerExt2.start();
//		sellerExt3.start();

/*
* implements实现方式则可以实现多窗口卖票(3个窗口买10张票)
*/
ThreadImplt seller = new ThreadImplt(TOTAL_TICKETS);
Thread window1 = new Thread(seller);
Thread window2 = new Thread(seller);
Thread window3 = new Thread(seller);

Date begin2 = new Date();
window1.start();
window2.start();
window3.start();
Date end2 = new Date();
long millisTotal2 = end2.getTime()-begin2.getTime();
System.out.println(TOTAL_TICKETS + " tikcets sold in " + millisTotal2 + " miliseconds.");
}
}

class ThreadExtends extends Thread
{
/*
* 总票数
*/
private int ticket;

/**
* Creates a new instance of ThreadExtends.
*
* @param ticket
*/

public ThreadExtends(int ticket)
{
this.ticket = ticket;
}

/**
*
* TODO 执行-买票.
* @see java.lang.Thread#run()
*/
public void run()
{
while (true)
{
if (ticket > 0)
{
System.out.println("[Window " + Thread.currentThread().getId() + "] is sailing tiket " + ticket--);
try
{
Thread.sleep(10);
}
catch (InterruptedException e)
{
//日志处理
throw new RuntimeException(e.toString()+"errorCode");
}
}
else
{
break;
}
}
}
}

class ThreadImplt implements Runnable
{
/*
* 总票数
*/
private int ticket;

/**
* Creates a new instance of ThreadImplt.
*
* @param ticket
*/

public ThreadImplt(int ticket)
{
this.ticket = ticket;
}

/**
* TODO 执行-买票.
* @see java.lang.Runnable#run()
*/
@Override
public void run()
{
while (true)
{
if (ticket > 0)
{
System.out.println("[Window " + Thread.currentThread().getId() + "] is sailing tiket " + ticket--);
try
{
Thread.sleep(10);
}
catch (InterruptedException e)
{
//日志处理
throw new RuntimeException(e.toString()+"errorCode");
}
}
else
{
break;
}
}
}
}


总结

java 共两种创建线程的方式:

一、无返回类,又分为两大类即 实现Runnable接口 与 继承 Thread 类(extends Thread 实际也属于实现Runnbale接口类 - Thread本身实现了Runnbale接口)。

 我们很多情况下要把一个类的子类放到多线程中去,这个时候就就只能 通过implement创建: java单继承
 相同程序代码的线程去处理同一个资源。比如说,铁路售票系统的模拟。

二、有返回类,即 实现Callable接口。

参考文献

1、三种实现线程的方式 http://www.cnblogs.com/yezhenhan/archive/2012/01/09/2317636.html  感谢博主!

2、 张孝祥-Java多线程与并发库高级应用 向张老师致敬!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: