进程与线程的区别 :
(1)一个线程只属于一个进程,一个进程可以有多个线程
(2)进程间相互独立,线程共享进程的内存空间和资源
(3)进程是分配资源的单位,有独立的地址空间
(4)线程是处理器调度的基本单位
进程间通信的几种方式:
(1)管道。半双工通信方式,常用于有亲缘关系的父子进程
(2)命名管道。用于没有亲缘关系的进程
(3)消息队列。存放在内核,克服信号和管道的缺点
(4)共享内存。一个进程创建,多个进程共享,通常与信号量一起使用,实现进程间的通信与同步
(5)信号。通知某个事件发生
(6)信号量,是一个计数器,用来控制多进程对共享资源的访问,是一种锁机制,解决进程间的互斥与同步
为什么使用多线程
使用多线程,可以把一些大任务分解成多个小任务来执行,多个小任务之间互不影像,同时进行,这样,充分利用了cpu资源。
实现多线程的两种方式:
(1)继承Thread类,重写run方法;
(2)实现Runable接口,实现run方法;
线程的状态:
新建,就绪,运行,阻塞,死亡
线程池的作用:
(1)降低资源消耗,可重复利用
(2)加快响应速度,不需要重复创建
(3)便于管理
spring 中的线程池
Spring中的线程池是由ThreadPoolTaskExecutor类来实现的
Java代码初始化:
private void test2(){ ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(10); executor.setMaxPoolSize(15); executor.setKeepAliveSeconds(1); executor.setQueueCapacity(5); executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); executor.initialize(); executor.execute(new Runnable(){ @Override public void run() { //执行的代码 } });}复制代码
线程通信
1.通信方式
(1)等待通知机制:两个线程通过对同一对象调用等待wait()和通知notify()方法来进行通信
案例:两个线程交替打印奇偶数
(2)join()方法:其实也是调用等待通知机制
(3)volatile共享内存:java采用共享内存的方式进行同信(也可以使用管道)
(4)线程响应中断
(5)线程池的awaitTermination() 方法
(6)管道通信
volatile关键字
典型案例:i++和++i不是原子操作
作用:保证内存可见性和防止 JVM 进行指令重排优化
解释:cpu的速度往往与内存的速度很难匹配,所以在cpu和内存之间加入高速缓存(每个线程都有自己的高速缓存),在cpu没有命中高速缓存的时候才会去内存中取,在并发编程中就会出现高速缓存没有同步到内存中的情况。
用volatile修饰的变量会强制任何线程对此变量的操作都会立即刷新到主内存中,并且强制让缓存了此变量的栈清空,必须从主内存中获取数据,保证了一致性(注意,修饰之后并不是让线程从主内存中取,依然将变量拷贝到缓存区)。所以可以保证取出的值一定是最新的,但是注意:volatile并不保证原子性,不保证线程安全性