并发编程002 --- 线程的基本使用
线程状态
1、OS层面
初始状态----可运行状态-----运行状态-------阻塞状态-------终止状态
2、java语言层面
初始状态----运行状态-------等待状态------限时等待状态-------终止状态
java语言层面,无法区分线程是可运行还是运行(OS层面的状态)
基本使用 --- 创建、运行、休眠、让步
1、创建
继承Thread类,并重写run方法;实现Runnable接口类;创建后进入初始状态
2、运行
Thread类的start方法;进入运行态
3、休眠
sleep方法,进入阻塞态,线程休眠期间,任意线程可获得执行权,超时后,重新等待CPU调度。
4、让步
yield方法,只是让当前线程暂停,不会进入阻塞态,期间,只有相同优先级或者更高优先级的线程可获得执行权。
从源码即可看出sleep和yield的区别,sleep会抛出InterruptedException异常,而yield不会。
等待通知 --- wait、notify、notifyAll
wait、notify和notifyAll方法并不是Thread类提供的方法,而是Object类提供的方法
wait方法:使当前执行代码的线程进行等待,并且将该线程放入等待队列中,直到被其他线程通知执行,此时释放锁;
执行条件为:必须获取到该对象的对象级别的锁,而且wait方法必须在同步方法或者同步代码块中执行。
notify方法:通知等待队列上的线程继续执行,执行条件和wait方法相同
notifyAll方法:通知等待队列上的所有线程继续执行,执行条件和wait方法相同
典型示例为生产者、消费者模式
public class BlockingQ { private LinkedList<Integer> valueList = new LinkedList<>(); private final Object lock = new Object(); private static final int MAX_SIZE = 3; public void produce() { Integer value = new Random().nextInt(); synchronized (lock) { while (this.valueList.size() >= MAX_SIZE) { System.out.println("Thread " + Thread.currentThread().getName() + " produce wait."); try { lock.wait(); } catch (InterruptedException e) { System.out.println("Produce interrupted!!"); } } System.out.println("Thread " + Thread.currentThread().getName() + " produce value."); this.valueList.add(value); lock.notifyAll(); } } public void consume() { synchronized (lock) { while (valueList.size() <= 0) { System.out.println("Thread " + Thread.currentThread().getName() + " consume wait."); try { lock.wait(); } catch (InterruptedException e) { System.out.println("Consume interrupted!!"); } } System.out.println("Thread " + Thread.currentThread().getName() + " consume value."); valueList.remove(0); lock.notifyAll(); } } }
生产者:
public class Producer implements Runnable { private BlockingQ blockingQ; public Producer(BlockingQ blockingQ) { this.blockingQ = blockingQ; } @Override public void run() { blockingQ.produce(); } }
消费者:
public class Consumer implements Runnable { private BlockingQ blockingQ; public Consumer(BlockingQ blockingQ) { this.blockingQ = blockingQ; } @Override public void run() { blockingQ.consume(); } }
执行方法:
public class Main { public static void main(String[] args) { BlockingQ blockingQ = new BlockingQ(); Producer producer = new Producer(blockingQ); Consumer consumer = new Consumer(blockingQ); // producer Thread thread1 = new Thread(producer); Thread thread2 = new Thread(producer); Thread thread3 = new Thread(producer); Thread thread4 = new Thread(producer); // consumer Thread thread5 = new Thread(consumer); Thread thread6 = new Thread(consumer); Thread thread7 = new Thread(consumer); Thread thread8 = new Thread(consumer); thread1.start(); thread2.start(); thread3.start(); thread4.start(); thread5.start(); thread6.start(); thread7.start(); thread8.start(); } }
执行结果:
心有猛虎,细嗅蔷薇