线程&&进程
线程在日常开发中经常见到,当需要执行某段耗时操作,开发者会开启一个线程去执行该任务。
- 线程:
- 进程中负责程序执行的执行单元
- 依靠程序执行的顺序控制流,只能使用程序的资源和环境,共享进程的全部资源
- 有自己的堆栈和局部变量,没有单独的地址空间
- CPU调度和分派的基本单位,持有程序计数器,寄存器,堆栈
- 进程:
- 系统资源分配和调度的独立单位
- 至少包含一个线程
- 拥有自己的资源
线程创建
线程创建有两种方式通过继承 Thread和实现Runnable接口。
- Thread 创建
class Thread1 extends Thread {
@Override
public void run() {
System.out.println("thread 创建线程---" + getName());
}
}
- 实现Runnable 接口
class Thread1 extends Thread {
@Override
public void run() {
System.out.println("thread 创建线程---" + getName());
}
}
整体调用如下
public class ThreadDemo1 {
public static void main(String[] args) {
Thread1 thread1 = new Thread1();
thread1.start();
Thread thread2 = new Thread(new Runnable1());
thread2.start();
}
}
运行查看结果:


可以看到两次运行的记过不一样,这就再次证明线程运行顺序与线程提交时间无关。
/notify/notifyAllwait 方法
wait/notify/notifyAll方法是Object的本地final方法,无法被重写。wait()使当前线程阻塞,前提是 必须先获得锁,一般配合synchronized 关键字使用,即,一般在synchronized 同步代码块里使用 wait()、notify/notifyAll 方法。在使用wait方法的时候说明该线程一定是持有锁。
举个常见的消费者生产者的例子,工厂,仓库,消费者。
工厂:负责生产商品,输入到仓库
消费者:消耗商品,从仓库取出商品。
仓库:存储商品,仓库满了的时候会通知工厂暂停生产,仓库一旦有空位,通知工厂生产。
package com.oracle.storage;
public interface GoodsFactory {
/**
* 生产
* @param number
*/
public void produce(int number);
/**
* 消费
* @param number
*/
public void consume(int number);
}
生产消费商品:
package com.oracle.storage;
import java.util.LinkedList;
public class ImpFactory implements GoodsFactory {
private int MAX = 100;//仓库最大容量
LinkedList<String> linkedList;
public ImpFactory(LinkedList<String> linkedList) {
this.linkedList = linkedList;
}
@Override
public void produce(int number) {
synchronized (linkedList){
//生产的数量和存储量大于仓库总量,暂停生产
while (linkedList.size()+number>MAX){
System.out.println("生产的数量和存储量大于仓库总量,暂停生产");
try {
linkedList.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int i =0;i<number;i++){
linkedList.add("商品"+i);
}
System.out.println("商品生产足够,商品总量为"+linkedList.size());
linkedList.notifyAll();
}
}
@Override
public void consume(int number) {
synchronized (linkedList){
//生产的数量和存储量大于仓库总量,暂停生产
while (number>linkedList.size()){
System.out.println("消耗的数量"+number+"大于仓库总量,请等待生产,仓库总量为:"+linkedList.size());
try {
linkedList.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int i =0;i<number;i++){
linkedList.remove();
}
System.out.println("消耗了商品"+number+"件,商品剩余量为"+linkedList.size());
linkedList.notifyAll();
}
}
}
验证:
package com.oracle.storage;
import java.util.LinkedList;
public class Main {
public static void main(String[] args) {
LinkedList<String> linkedList = new LinkedList<>();
Producer producer1 = new Producer(new ImpFactory(linkedList),80);
Producer producer2= new Producer(new ImpFactory(linkedList),20);
Producer producer3= new Producer(new ImpFactory(linkedList),30);
Producer producer4= new Producer(new ImpFactory(linkedList),40);
Consumer consumer = new Consumer(new ImpFactory(linkedList),30);
producer1.start();
producer2.start();
producer3.start();
producer4.start();
consumer.start();
}
static class Producer extends Thread{
int number;
ImpFactory impFactory ;
public Producer(ImpFactory abstractStorage,int number){
impFactory = abstractStorage;
this.number = number;
}
@Override
public void run() {
impFactory.produce(number);
}
}
static class Consumer extends Thread{
int number;
ImpFactory impFactory ;
public Consumer(ImpFactory abstractStorage,int number){
impFactory = abstractStorage;
this.number = number;
}
@Override
public void run() {
impFactory.consume(number);
}
}
}
如此可以初步了解 /notify/notifyAllwait 方法。
网友评论