六:多线程综合案例

1、数字加减

          设计4个线程对象,两个线程执行减操作,两个线程执行加操作。

          范例:程序代码如下

package cn.demos;

//定义一个操作的资源
class Resoure {
	// 定义一个要进行加减操作的数据
	private int num = 0;
	// 加减的切换
	// 如果flag等于true,表示进行加法操作,不能进行减法操作;
	// 如果flag等于false,表示进行减法操作,不能进行加法操作;
	private boolean flag = true;

	// 执行加法操作
	public synchronized void add() throws Exception {
		if (this.flag == false) {// flag == false,则执行减法操作,加法操作等待着
			super.wait();
		}

		Thread.sleep(100);
		this.num++;
		System.out.println("加法操作!!!!" + Thread.currentThread().getName() + "===num==" + this.num);
		this.flag = false;// 加法操作执行完毕,需要执行减法操作。
		// 唤醒全部等待线程
		super.notifyAll();

	}

	// 执行减法操作
	public synchronized void sub() throws Exception {
		if (this.flag == true) {// 减法操作需要等待
			super.wait();
		}
		Thread.sleep(200);
		this.num--;
		System.out.println("减法操作!!!!" + Thread.currentThread().getName() + "===num==" + this.num);
		this.flag = true;
		// 唤醒全部等待线程
		super.notifyAll();
	}
}

// 准备一个加线程
class AddThread implements Runnable {

	// 引入Resource
	private Resoure resoure;

	public AddThread(Resoure resoure) {
		this.resoure = resoure;
	}

	@Override
	public void run() {
		for (int x = 0; x < 50; x++) {
			try {
				this.resoure.add();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

}

// 准备一个减线程
class SubThread implements Runnable {

	// 引入Resource
	private Resoure resoure;

	public SubThread(Resoure resoure) {
		this.resoure = resoure;
	}

	@Override
	public void run() {
		for (int x = 0; x < 50; x++) {
			try {
				this.resoure.sub();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

}

public class ThreadDemo1 {

	public static void main(String[] args) {
		Resoure res = new Resoure();
		// 加法线程
		AddThread at = new AddThread(res);
		// 减法线程
		SubThread st = new SubThread(res);
		new Thread(at, "加法线程 - A").start();
		new Thread(at, "加法线程 - B").start();
		new Thread(st, "减法线程 - C").start();
		new Thread(st, "减法线程 - D").start();
	}

}
执行结果(部分)加法操作!!!!加法线程 - B===num==1
减法操作!!!!减法线程 - C===num==0
加法操作!!!!加法线程 - B===num==1
减法操作!!!!减法线程 - D===num==0
加法操作!!!!加法线程 - A===num==1
减法操作!!!!减法线程 - D===num==0
加法操作!!!!加法线程 - B===num==1
减法操作!!!!减法线程 - C===num==0
加法操作!!!!加法线程 - B===num==1
减法操作!!!!减法线程 - D===num==0
加法操作!!!!加法线程 - A===num==1
减法操作!!!!减法线程 - D===num==0
加法操作!!!!加法线程 - B===num==1
减法操作!!!!减法线程 - C===num==0
加法操作!!!!加法线程 - B===num==1

          从执行结果来看,可以得知,四个线程交替执行,执行结果在1和0和-1之间反复横跳。

 

2、生产电脑

          设计一个生产电脑和搬运电脑类,要求生产出一台电脑就搬走一台电脑,如果没有新的电脑生产出来则搬运工要等待新电脑产出;如果生产出的电脑没有搬走,则要等待电脑搬走之后再生产,并统计出生产的电脑数量。

          范例:具体实现代码

package cn.demos;

class Computer {
	// 表示生产的个数
	private static int count = 0;
	// 电脑名字
	private String name;
	// 电脑价格
	private double price;

	public Computer(String name, double price) {
		this.name = name;
		this.price = price;
		count++;
	}

	@Override
	public String toString() {
		return "第" + count + "台" + "computer [name=" + this.name + ", price=" + price + "]";
	}

}

class Resource {
	// 定义一个标记
	private boolean flag = true;
	private Computer computer;

	// 生产电脑
	public synchronized void make() throws Exception {
		if (this.computer != null) {// 已经生产过了
			super.wait();
		}
		Thread.sleep(100);
		this.computer = new Computer("DELL牌", 10000);
		System.out.println("生产电脑" + this.computer);
		super.notifyAll();

	}

	// 获得电脑
	public synchronized void get() throws Exception {
		if (this.computer == null) {// 没有生产过
			super.wait();
		}
		Thread.sleep(100);
		System.out.println(this.computer);
		System.out.println("取走电脑" + this.computer);
		// 将computer的值设置为null,表示已经取走了电脑
		this.computer = null;
		super.notifyAll();

	}
}

// 生产者线程
class Producer1 implements Runnable {

	private Resource resource;

	public Producer1(Resource resource) {
		this.resource = resource;
	}

	@Override
	public void run() {
		for (int x = 0; x < 50; x++) {
			try {
				this.resource.make();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

}

// 消费者线程
class Consumer1 implements Runnable {

	private Resource resource;

	public Consumer1(Resource resource) {
		this.resource = resource;
	}

	@Override
	public void run() {
		for (int x = 0; x < 50; x++) {
			try {
				this.resource.get();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

}

public class ThreadDemo1 {

	public static void main(String[] args) {
		Resource res = new Resource();
		new Thread(new Producer1(res)).start();
		new Thread(new Consumer1(res)).start();

	}

}
代码执行结果部分展示生产电脑第1台computer [name=DELL牌, price=10000.0]
第1台computer [name=DELL牌, price=10000.0]
取走电脑第1台computer [name=DELL牌, price=10000.0]
生产电脑第2台computer [name=DELL牌, price=10000.0]
第2台computer [name=DELL牌, price=10000.0]
取走电脑第2台computer [name=DELL牌, price=10000.0]
生产电脑第3台computer [name=DELL牌, price=10000.0]
第3台computer [name=DELL牌, price=10000.0]
取走电脑第3台computer [name=DELL牌, price=10000.0]
生产电脑第4台computer [name=DELL牌, price=10000.0]
第4台computer [name=DELL牌, price=10000.0]
取走电脑第4台computer [name=DELL牌, price=10000.0]
生产电脑第5台computer [name=DELL牌, price=10000.0]
第5台computer [name=DELL牌, price=10000.0]
取走电脑第5台computer [name=DELL牌, price=10000.0]
生产电脑第6台computer [name=DELL牌, price=10000.0]
第6台computer [name=DELL牌, price=10000.0]
取走电脑第6台computer [name=DELL牌, price=10000.0]
生产电脑第7台computer [name=DELL牌, price=10000.0]
第7台computer [name=DELL牌, price=10000.0]
取走电脑第7台computer [name=DELL牌, price=10000.0]
生产电脑第8台computer [name=DELL牌, price=10000.0]
第8台computer [name=DELL牌, price=10000.0]
取走电脑第8台computer [name=DELL牌, price=10000.0]
生产电脑第9台computer [name=DELL牌, price=10000.0]
第9台computer [name=DELL牌, price=10000.0]
取走电脑第9台computer [name=DELL牌, price=10000.0]
生产电脑第10台computer [name=DELL牌, price=10000.0]
第10台computer [name=DELL牌, price=10000.0]
取走电脑第10台computer [name=DELL牌, price=10000.0]

          上面代码是一个典型的生产者与消费者案例模型。

3、竞争抢答

          实现一个竞拍抢答程序:要求设置三个抢答者(三个线程),而后同时发出抢答指令,抢答成功者给出提示,未抢答成功者给出失败提示。

          针对这个程序分析,这个程序里面牵扯到数据的返回问题,所以,在这里可以使用到我们前面提到的Callable来处理。

          范例:程序实现代码

package cn.demos;
//多线程综合案例三:抢答问题的设计

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

class MyThread implements Callable<String> {

	private boolean flag = false;// 抢答处理

	@Override
	public String call() throws Exception {
		synchronized (this) {// 数据同步
			if (this.flag == false) {// 抢答成功
				this.flag = true;
				return Thread.currentThread().getName() + "抢答成功";
			} else {
				return Thread.currentThread().getName() + "抢答失败";

			}
		}
	}

}

public class ThreadDemo2 {

	public static void main(String[] args) throws Exception {
		MyThread mt = new MyThread();
		FutureTask<String> taskA = new FutureTask<String>(mt);
		FutureTask<String> taskB = new FutureTask<String>(mt);
		FutureTask<String> taskC = new FutureTask<String>(mt);
		new Thread(taskA, "竞赛者A").start();
		new Thread(taskB, "竞赛者B").start();
		new Thread(taskC, "竞赛者C").start();
		System.out.println(taskA.get());
		System.out.println(taskB.get());
		System.out.println(taskC.get());

	}

}
结果竞赛者A抢答成功
竞赛者B抢答失败
竞赛者C抢答失败
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值