您的位置:首页 > 编程语言 > Java开发

Java多线程(四) Thread和Runnable之区别(售票系统)

2014-11-15 17:10 603 查看
Thread和Runnable之区别(售票系统)

两种方式有什么不同,利用Runnable可以实现资源共享:

一、售票系统用Thread进行实现如下:

public class TicketThread extends Thread {

private int ticket = 5;// 总共5张票

@Override

public void run() {

while (true)

if (ticket > 0)

System.out.println(Thread.currentThread().getName() + ":正在卖第" + ticket-- + "张票 ... ... ");

}

public static void main(String[] args) {

// 创建3个线程

TicketThread tt1 = new TicketThread();

TicketThread tt2 = new TicketThread();

TicketThread tt3 = new TicketThread();

// 启动线程

tt1.start();

tt2.start();

tt3.start();

}

}

运行结果如下:

Thread-2:正在卖第5张票 ... ...

Thread-2:正在卖第4张票 ... ...

Thread-2:正在卖第3张票 ... ...

Thread-2:正在卖第2张票 ... ...

Thread-2:正在卖第1张票 ... ...

Thread-0:正在卖第5张票 ... ...

Thread-0:正在卖第4张票 ... ...

Thread-0:正在卖第3张票 ... ...

Thread-0:正在卖第2张票 ... ...

Thread-0:正在卖第1张票 ... ...

Thread-1:正在卖第5张票 ... ...

Thread-1:正在卖第4张票 ... ...

Thread-1:正在卖第3张票 ... ...

Thread-1:正在卖第2张票 ... ...

Thread-1:正在卖第1张票 ... ...

一共5张票,实际执行结果却是卖了15张票。从中可以看出使用Thread不能够实现数据共享的效果。

二、售票系统用Runnable进行实现如下:

public class TicketRunnable implements Runnable {

private int ticket = 5;// 总共5张票

@Override

public void run() {

while (true)

if (ticket > 0)

System.out.println(Thread.currentThread().getName() + ":正在卖第" + ticket-- + "张票 ... ... ");

}

public static void main(String[] args) {

// 利用实例化一个Runnable对象,实现共享

TicketRunnable tr = new TicketRunnable();

// 创建3个线程

Thread tt1 = new Thread(tr, "1号窗户");

Thread tt2 = new Thread(tr, "2号窗户");

Thread tt3 = new Thread(tr, "3号窗户");

// 启动线程

tt1.start();

tt2.start();

tt3.start();

}

}

运行结果如下:

1号窗户:正在卖第5张票 ... ...

3号窗户:正在卖第3张票 ... ...

2号窗户:正在卖第4张票 ... ...

3号窗户:正在卖第1张票 ... ...

1号窗户:正在卖第2张票 ... ...

一共5张票,实际执行结果也是卖了5张票。从中可以看出使用Runnable能够实现数据共享的效果。

利用实例化一个Runnable对象,实现共享。

三、通过只实例化一个Runnable对象来进行共享资源。

需求:主线程和子线程都是并发执行的,也就是当子线程在执行的过程中,主线程也在往下执行。主线程需要所有子线程返回执行结果才能继续执行。

我们利用一个CountDownLatch来实现。

CountDownLatch,一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。

主要方法
public CountDownLatch(int count);
public void countDown();
public void await() throws InterruptedException

构造方法参数指定了计数的次数

countDown方法,当前线程调用此方法,则计数减一

awaint方法,调用此方法会一直阻塞当前线程,直到计时器的值为0

实例如下:
import java.util.concurrent.CountDownLatch;

public class MyRunnableReturn implements Runnable {

private CountDownLatch threadsSingal;

public MyRunnableReturn(CountDownLatch threadsSingal) {

super();

this.threadsSingal = threadsSingal;

}

public void run() {

System.out.println(Thread.currentThread().getName() + "--开始");

System.out.println(Thread.currentThread().getName() + "--结束");

threadsSingal.countDown();// 线程减1

}

public static void main(String[] agrs) {

System.out.println("Main --开始");

CountDownLatch threadsSingal = new CountDownLatch(3);

MyRunnableReturn myRunnable = new MyRunnableReturn(threadsSingal);

new Thread(myRunnable, "thread1").start();

new Thread(myRunnable, "thread2").start();

new Thread(myRunnable, "thread3").start();

try {

threadsSingal.await();// 等待所有子线程执行完

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("Main --结束");

}

}

运行结果如下:

Main --开始

thread1--开始

thread1--结束

thread3--开始

thread3--结束

thread2--开始

thread2--结束

Main --结束

综上实例可以看出,达到了需求的效果。先执行所有子线程,再运行主线程。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: