指令的运行和数据的读写依赖于将指令加载到CPU,数据加载到内存,在指令运行过程中还需要用到IO设备
是否能在系统中打开多份
将指令流中的指令交给CPU执行
一个进程中可以有多个线程
进程是运行程序的实例,进程包含了多个线程,每个线程任务不同
不同进程使用不同内存空间,当前进程下的所有线程可以共享内存空间
线程更加轻量,切换相较进程成本低
对于单核CPU来说,所有线程都是串行执行,将时间片分给不同的程序使用,在不同线程间来回切换.(并发)
对于多核CPU来说,就可以实现并行执行,不同核心在同一时间片内执行不同线程.(并行)
NEW
//等待启动
RUNNABLE
//可运行
BLOCKED
//阻塞
WAITING
//等待
TIMED_WAITING
//指定等待时间
TERMINATED
//终止
新线程(NEW)在start()方法启动时变为就绪状态->运行状态(RUNNABLE),运行结束后终止被回收(TERMINATED)
如果加锁,线程被锁阻塞即BLOCKED状态
如果被wait()即WAITING状态
如果被sleep(100)即TIMED_WAITING状态
//重写run方法
class MyThread() extends Thread{
@Override
public void run(){
}
}
//重写run方法
class MyRunnable inplements Runnable{
@Override
public void run(){
}
}
//重写call方法
class MyCallable implements Callable<String>{
@Override
public String call(){
}
}
main(){
MyCallable mc = new MyCallable();
FutureTask<String> ft = new FutureTask<String>(mc);
Thread t1 = new Thread(ft);
String result = ft.get();
}
//创建线程池对象
public ThreadPoolExecutor(
int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQuene workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler
)
new ThreadPoolExecutor(...);
TE.submit()
corePoolSize:指定线程池的核心线程数量
maximumPoolSize:指定线程池的最大线程数量(核心+临时)
keepAliveTime:指定临时线程的存活时间
unit:指定临时线程存活的时间单位(秒,分,时,天)
workQueue:指定线程池的任务队列,阻塞队列(BlockingQueue<>的实现类对象)
threadFactory:指定线程池的线程工厂(创建线程的地方)
handler:指定线程池的任务拒绝策略(任务队列满时,新任务来怎么处理)
1,Runnable接口run方法没有返回值,但callable接口call方法有泛型返回值,和Future和FutureTask配合可以用以获取异步执行的结果
2,call()方法允许抛出异常,但run()方法抽象方法声明时没有抛出,所以run()方法重写时只能在内部处理不能抛出
使用start()启动,只能执行一次调用run方法中的逻辑,(开启线程执行)
使用join()方法可以阻塞当前的线程,直到调用join()方法的线程执行完毕才会继续执行
eg:
new Thread(()->{
t1.join;
})
直到线程t1执行结束之后才会继续执行
notify():随机唤醒一个线程
notifyAll():唤醒所有wait()的线程
同:都能让目前线程暂时放弃cpu使用权,陷入阻塞状态
异:
sleep()方法是Thread的静态方法
wait()方法是Object的成员方法
sleep(100)和wait(100)都会在对应时间后醒来
但wait()如果不被唤醒就会一直阻塞
都可以被打断唤醒
wait方法的调用必须先获取wait对象的锁,(必须和synchronized一起使用)
sleep不需要
wait方法执行后会先释放锁,允许其他线程竞争
但sleep方法执行后不会释放锁