编发编程基础
进程
进程 就是分配资源的最小单位,进程可以实现宏观上(cpu时间片不断去切换)的并发,单核任意一个时刻cpu只会有一个任务去执行。
指令切换要对指令进行隔离:
- 给每一个进程分配内存地址空间,并且不同的进程空间是不会相互干扰的,
- 进程需要记住每个指令运行的行数,计数器。
线程
一个进程可以包含多个线程,每个线程可以有一个独立的子任务.利用多cpu的性质,就可以同时并行执行。达到并行效果。线程让我们真正意义上实现了并行执行。线程是执行任务的最小单位。
线程的目的就是为了能够解决我们多任务的实时性问题,解决阻塞问题。
什么时候使用多线程?
- 通过并行计算提高程序性能,对复杂逻辑计算使用多线程
- 等待网络、IO、响应导致的耗时问题。(例如:tomcat中IO 的模型,一个请求开一个线程去处理,主流程不会阻塞)
java中多线程的实现方式:
- 继承Tread类,重写run方法
- 实现Runnable接口重写run方法
- 通过Callable,future实现,继承Callable,重写callI()方法,实现带返回值的线程
public class CallableDemo implements Callable<String> {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//创建线程池
ExecutorService executorService = Executors.newCachedThreadPool();
CallableDemo callableDemo = new CallableDemo();
//交给线程池异步执行call()方法中的逻辑
Future<String> future = executorService.submit(callableDemo);
//todo 执行其他逻辑操作
//获取异步执行结果,如果call中有结果返回,就立马返回,如果没有结果返回就阻塞等待
String s = future.get();
System.out.println(s);
executorService.shutdown();
}
@Override
public String call() {
//todo 有很多耗时的逻辑运算
return "string" + 1;
}
}
线程的状态:
线程的状态:6 种
NEW 没有调用start方法
RUNNABLE 运行状态
BOLCKED 阻塞
WAITING 等待
TIMED_WAITING 时间等待
TERMINATED 终止
在Thread类里,有一个state的枚举类型,声明了线程的六种状态
public enum State {
/**
* Thread state for a thread which has not yet started.
*/
NEW,
/**
* Thread state for a runnable thread. A thread in the runnable
* state is executing in the Java virtual machine but it may
* be waiting for other resources from the operating system
* such as processor.
*/
RUNNABLE,
/**
* Thread state for a thread blocked waiting for a monitor lock.
* A thread in the blocked state is waiting for a monitor lock
* to enter a synchronized block/method or
* reenter a synchronized block/method after calling
* {@link Object#wait() Object.wait}.
*/
BLOCKED,
/**
* Thread state for a waiting thread.
* A thread is in the waiting state due to calling one of the
* following methods:
* <ul>
* <li>{@link Object#wait() Object.wait} with no timeout</li>
* <li>{@link #join() Thread.join} with no timeout</li>
* <li>{@link LockSupport#park() LockSupport.park}</li>
* </ul>
*
* <p>A thread in the waiting state is waiting for another thread to
* perform a particular action.
*
* For example, a thread that has called <tt>Object.wait()</tt>
* on an object is waiting for another thread to call
* <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
* that object. A thread that has called <tt>Thread.join()</tt>
* is waiting for a specified thread to terminate.
*/
WAITING,
/**
* Thread state for a waiting thread with a specified waiting time.
* A thread is in the timed waiting state due to calling one of
* the following methods with a specified positive waiting time:
* <ul>
* <li>{@link #sleep Thread.sleep}</li>
* <li>{@link Object#wait(long) Object.wait} with timeout</li>
* <li>{@link #join(long) Thread.join} with timeout</li>
* <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
* <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
* </ul>
*/
TIMED_WAITING,
/**
* Thread state for a terminated thread.
* The thread has completed execution.
*/
TERMINATED;
}
线程状态的转换图
线程的中断
线程的中断不是调用stop方法,要使用interrupt去执行线程的中断(优雅的退出,收到interrupt指令后,线程不再接收新的任务,但是会把尚未执行完的任务,执行完成再退出)。
线程安全性问题:
可见性、原子性、有序性
多核心CPU技术的出现 导致了 可见性,原子性,有序性的问题
cpu的高速缓存:
在cpu和内存之间会存在一个缓存,叫cpu的高速缓存。
缓存一致性问题
缓存一致性协议,嗅探协议。cpu的一个实现(不同的处理器,提供的协议不同):
M(modify) 表示当前缓存被修改过
I(Invalid) 表示失效状态,cpu会直接从主内存加载
E(Exclusive) 表示独占缓存,且与主内存中的数据保持一致
S(Shared) 共享缓存
可见性问题?
- 缓存一致性
- 乱序执行(happen-before 原则保证语义不变)
- 内存乱序访问