生产者与消费者问题 线程基础篇
线程常涉及的若干方法
Object
notify()//唤醒在此对象监视器上等待的单个线程
notifyAll()//唤醒在此对象监视器上所有等待的所有线程
wait() //导致当前线程等待,由notify(),notifyAll()唤醒
Thread
Thread()
Thread(Runable target)
Thread(Runable target, String name)
currentThread() //返回当前正在执行的线程对象的引用
getId()//返回该线程的线程号
getName()//返回该线程的名称
interrupt()//中断线程
interrupted() //测试该线程是否已经中断 静态方法
isAlive()//测试该线程是否处于活动状态
isInterrupted() //测试该线程是否已经中断
join()//等待该线程终止
sleep()//睡眠
start()//启动线程
yield()//暂停当前正在执行的线程对象,并执行其他线程 静态方法
Runnable
run()
创建线程
public class ThreadTest extends Thread { public void run() { System.out.println("@run() 子线程号:" + Thread.currentThread().getId()); for(int i=0; i<5; i++) System.out.println("i=" + i); } public static void main(String[] args) { ThreadTest tt = new ThreadTest(); tt.start(); System.out.println("@main() 主程序的线程号:" + Thread.currentThread().getId()); }}
public class RunnableTest implements Runnable { public void run() { System.out.println("@run() 子线程号:" + Thread.currentThread().getId()); for(int i=0; i<5; i++) System.out.println("i=" + i); } public static void main(String[] args) { Thread t = new Thread(new RunnableTest()); t.start(); System.out.println("@main() 主程序的线程号:" + Thread.currentThread().getId()); }}
import java.util.Date;class AsyncObj { public synchronized static void asyncStatic1() throws InterruptedException { System.out.println("进入asyncStatic1 " + new Date()); Thread.sleep(2000); System.out.println("离开asyncStatic1 " + new Date()); } public synchronized static void asyncStatic2() throws InterruptedException { System.out.println("进入asyncStatic2 " + new Date()); Thread.sleep(2000); System.out.println("离开asyncStatic2 " + new Date()); } public synchronized void async1() throws InterruptedException { System.out.println("进入async1 " + new Date()); Thread.sleep(2000); System.out.println("离开async1 " + new Date()); } public synchronized void async2() throws InterruptedException { System.out.println("进入async2 " + new Date()); Thread.sleep(2000); System.out.println("离开async2 " + new Date()); } public void nonAsync() throws InterruptedException { Thread.sleep(1000); System.out.println("进入nonAsync " + new Date()); System.out.println("离开nonAsync " + new Date()); } public static void nonAsyncStatic() throws InterruptedException { Thread.sleep(1000); System.out.println("进入nonAsyncStatic " + new Date()); System.out.println("离开nonAsyncStatic " + new Date()); }}public class AsyncTest extends Thread { public AsyncObj sharedObj; public int asyncTestThreadId; public AsyncTest(int asyncTestThreadId, AsyncObj sharedObj) { this.sharedObj = sharedObj; this.asyncTestThreadId = asyncTestThreadId; } public void run() { try { switch(asyncTestThreadId) { case 0: sharedObj.async1(); //锁定实例对象 break; case 1: sharedObj.async2(); break; case 2: sharedObj.nonAsync(); break; case 3: AsyncObj.asyncStatic1(); //锁定类对象 break; case 4: AsyncObj.asyncStatic2(); break; case 5: AsyncObj.nonAsyncStatic(); break; } } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) { AsyncObj sharedObj = new AsyncObj(); // 被访问的实例对象 AsyncTest[] threads = new AsyncTest[6]; // 多个访问线程 for (int i = 0; i < 6; i++) { threads[i] = new AsyncTest(i, sharedObj); threads[i].start(); } }}
//消费者与生产者例子介绍 wait(),notify(),notifyAll()//wait(),notify(),notifyAll()只能在同步方法或同步控制块中调用class Disk { private int apple; // number=1 有苹果 number=0 无苹果 public Disk(int apple) { this.apple = apple; } //消费者调用消费苹果 public synchronized void takeApple() { String name = Thread.currentThread().getName() + "线程: "; if (apple == 0) try { System.out.println(name + "盘子里面的苹果为空,等待生产者生产"); wait(); //消费者释放锁,使生产者能够进入addApple() } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(name + "盘子为满,开始消费一个苹果 花费5秒"); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(name + "盘子为满,结束消费一个苹果"); apple--; System.out.println(name + "唤醒生产者"); notifyAll(); } //生产者调用生产苹果 public synchronized void addApple() { String name = Thread.currentThread().getName() + "线程: "; if (apple == 1) try { System.out.println(name + "盘子为满,等待消费者消费"); wait(); //生产者释放锁,使消费者能够进入takeApple() } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(name + "盘子为空,开始生产一个苹果 花费3秒"); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(name + "盘子为空,结束生产一个苹果"); apple++; System.out.println(name + "唤醒消费者"); notifyAll(); }}class Producer implements Runnable { private Disk d; public Producer(Disk d) { this.d = d; } public void run() { while (true) { d.addApple(); } }}class Consumer implements Runnable { private Disk d; public Consumer(Disk d) { this.d = d; } public void run() { while (true) { d.takeApple(); } }}public class TestPC { public static void main(String[] args) { Disk d = new Disk(0); //初始化盘子为0个苹果 new Thread(new Consumer(d),"Consumer").start(); //启动消费者线程 new Thread(new Producer(d),"Producer").start(); //启动生产者线程 }}