一、多线程案例分析一:数字加减
设计四个线程,两个线程相加,两个线程相减
范例:代码
public class ThreadDemo5 { public static void main(String[] args) { Resource resource = new Resource(); AddThread addThread= new AddThread(resource); SubThread subThread = new SubThread(resource); new Thread(addThread,"加法线程A").start(); new Thread(addThread,"加法线程B").start(); new Thread(subThread,"减法线程X").start(); new Thread(subThread,"减法线程Y").start(); } } class Resource{ private int num = 0; private boolean flag = true; public synchronized void add(){ if(this.flag == false){ try { super.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } this.num++; System.out.println("【加法操作-"+Thread.currentThread().getName()+"】,num ="+this.num); this.flag=false; super.notifyAll(); } public synchronized void sub(){ if(this.flag == true){ try { super.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } this.num--; System.out.println("【减法操作-"+Thread.currentThread().getName()+"】,num ="+this.num); this.flag = true; super.notifyAll(); } } class AddThread implements Runnable{ private Resource resource; public AddThread(Resource resource){ this.resource = resource; } @Override public void run() { for(int i = 0; i<50; i++){ this.resource.add(); } } } class SubThread implements Runnable{ private Resource resource; public SubThread(Resource resource){ this.resource = resource; } @Override public void run() { for(int i = 0; i<50; i++){ this.resource.sub(); } } }
二、多线程案例分析二:生产电脑
设计一个生产电脑类和搬运电脑类,要求生产一台电脑就搬走一台电脑,如果没有新的电脑生产,则搬运工要等待新的电脑生产,如果电脑未搬走,则需要等待搬走后再生产,并统计出生产的电脑数量。
这是一个标准的生产者和消费者模型。
范例:代码
public class ThreadDemo6 { public static void main(String[] args) { Resource1 resource = new Resource1(); Producer1 p = new Producer1(resource); Customer1 c = new Customer1(resource); new Thread(p,"生产电脑").start(); new Thread(c,"搬运电脑").start(); } } 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+"台电脑],名字是"+this.name+"价格是"+this.price; } } class Producer1 implements Runnable{ private Resource1 resource; public Producer1(Resource1 resource){ this.resource = resource; } @Override public void run(){ for(int i = 0; i< 50 ; i++) { try { this.resource.make(); } catch (Exception e) { e.printStackTrace(); } } } } class Customer1 implements Runnable{ private Resource1 resource; public Customer1(Resource1 resource){ this.resource = resource; } @Override public void run(){ for(int i = 0; i<50; i++) { try { this.resource.get(); } catch (Exception e) { e.printStackTrace(); } } } } class Resource1{ private Computer computer; public synchronized void make() throws Exception{ if(this.computer != null){ super.wait(); } try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } this.computer = new Computer("华硕",666); System.out.println("生产电脑"+this.computer); super.notifyAll(); } public synchronized void get() throws Exception{ if(this.computer == null){ super.wait(); } try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("取走电脑"+this.computer); this.computer = null; super.notifyAll(); } }
三、多线程案例分析三:竞争抢答
实现一个竞拍抢答程序:要求设置三个抢答者(三个线程),而后同时发出抢答指令,抢答成功则给出成功提示,抢答失败给出失败提示。
因为涉及到了返回值的问题,所以最好用Callable实现。
范例:代码
public class ThreadDemo7 { public static void main(String[] args) throws Exception { ThreadTest threadTest = new ThreadTest(); FutureTask<String> taskA = new FutureTask<>(threadTest); FutureTask<String> taskB = new FutureTask<>(threadTest); FutureTask<String> taskC = new FutureTask<>(threadTest); 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()); } } class ThreadTest 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()+",抢答失败"; } } } }