文章目录
进程和线程
-
进程
- 进程是资源(CPU、内存等)分配的基本单位,它是程序执行时的一个实例。程序运行时系统就会创建一个进程,并为它分配资源,然后把该进程放入进程就绪队列,进程调度器选中它的时候就会为它分配CPU时间,程序开始真正运行。
- 简单来说,一个运行的程序就是一个进程。
-
线程
- 线程是程序执行时的最小单位,它是进程的一个执行流,是CPU调度和分派的基本单位。一个进程可以由很多个线程组成,线程间共享进程的所有资源,每个线程有自己的堆栈和局部变量。线程由CPU独立调度执行,在多CPU环境下就允许多个线程同时运行。同样多线程也可以实现并发操作每个请求分配一个线程来处理。
-
两者关系
- 进程是资源分配的最小单位,线程是程序执行的最小单位。
- 一个进程有多个线程。
实现多线程
继承Thread类
- 构造方法
public class Thread extends Object implements Runnable // Thread类继承了Runnable接口
// 静态方法
static Thread currentThread() 获得当前正在运行的线程
static class Thread.State 线程状态 枚举类
static void sleep(long millis) 线程调度 休眠(自己会醒过来) 让当前线程释放millis 并没有释放锁
static void yield() 当前线程让出抢占cpu资源机会 自己立马处于就绪状态
// 常用方法
long getId() 返回此线程的标识
String getName()
void setName(String name)
int getPriority() 设置运行优先级
void setPriority(int newPriority)
void join() 等待当前线程死亡 (指定顺序执行线程逻辑)
void join(long millis)
void start() 启动线程
void run() 运行
// 必须与锁结合使用
void wait() 等待 让当前线程一直处于等待的状态(线程死过去了)
void wait(long timeout)
void notify() /void notifyAll() 唤醒等待的线程
线程安全问题
sleep()和wait()的区别
为什么wait、notify、notifyAll方法定义在Object中而不是Thread类中
为什么wait、notify、notifyAll方法定义在Object中而不是Thread类中
发现一篇大神文章,不自己写了,直接转载
生产者和消费者
/**
* @author WangJie
* @version 1.0
* @Description:缓存池
* @date: 2020/6/2 21:06
* @since JDK 1.8
*/
public class OrderPool {
private OrderPool() {
}
private static List<String> pool = new CopyOnWriteArrayList<>();
public static synchronized void add(){
if (pool.size() == 20){
try {
OrderPool.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
String order = makeString();
pool.add(order);
System.out.println("生产者生产了一个字符串"+order+",目前池子里有:"+pool.size());
OrderPool.class.notify();
try {
Thread.sleep((int)(Math.random()*1000+500));// 时间区间[500,1500)
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static synchronized void remove(){
if (pool.size() == 0){
try {
OrderPool.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
int deal = (int) Math.random() * pool.size();
String name = pool.get(deal);
pool.remove(deal);
System.out.println("消费者消费了一个字符串"+name+",目前池子里有:"+pool.size());
OrderPool.class.notify();
try {
Thread.sleep((int)(Math.random()*1000+2000)); // 时间区间[2000,3000)
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private static String makeString(){
String source = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
char[] demo = source.toCharArray();
Random random = new Random();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 5; i++) {
sb.append(demo[random.nextInt(demo.length)]);
}
return sb.toString();
}
}
public class Customer implements Runnable {
@Override
public void run() {
while (true) {
OrderPool.remove();
}
}
}
public class Productor implements Runnable{
@Override
public void run() {
while (true){
OrderPool.add();
}
}
}
public class OrderTest {
public static void main(String[] args) {
new Thread(new Productor()).start();
new Thread(new Customer()).start();
}
}