1 编发编程的挑战
关键是回答红色部分的问题
2 上下文切换为什么会消耗大量时间?
2.1 上下文切换的概念
CPU通过时间片分配算法来循环执行任务,当前任务执行一个时间片后切换到下一个任务。但是,在切换前会保存上一个任务的状态,以便下次切换回这个任务时,可以加载这个任务的状态。所以任务从保存到再加载的过程就是一次上下文切换。
2.1 上下文切换需要保存哪些状态?
一个线程在运行时的内存模型主要有5个部分组成:(1)程序计数器:记录下一条指令的地址(2)虚拟机栈:保存函数的信息,例如,局部的变量,函数返回地址,操作数等(3)本地方法栈:和虚拟机栈类似,不过其保存的函数的信息是native函数(4)方法区:保存类的信息,静态变量等(5)堆:实例化的对象(堆是用户申请的,而栈是系统自动分配的)。很明显:程序计数器、虚拟机栈、方法区、堆等信息都会被保存到内存中。
3 如何减少上下文切换?
4 如何避免死锁?
4.1 死锁产生的4个必要条件
1、互斥:某种资源一次只允许一个进程访问,即该资源一旦分配给某个进程,其他进程就不能再访问,直到该进程访问结束。
2、占有且等待:一个进程本身占有资源(一种或多种),同时还有资源未得到满足,正在等待其他进程释放该资源。
3、不可抢占:别人已经占有了某项资源,你不能因为自己也需要该资源,就去把别人的资源抢过来。
4、循环等待:存在一个进程链,使得每个进程都占有下一个进程所需的至少一种资源。
public class DeadLockDemo {
private static String A = "A";
private static String B = "B";
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
synchronized(A){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (B) {
System.out.println("死锁");
}
}
}
}).start();
new Thread(new Runnable() {
public void run() {
synchronized(B){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (A) {
System.out.println("死锁");
}
}
}
}).start();
}
}
线程1获取A锁,等待B锁的释放。线程2获取了B锁,等待B锁的释放。产生了死锁。我们在window下查看死锁。
4.2 如何避免死锁
5 什么是资源限制问题?
资源限制是指在程序并发编程时,程序的执行速度受限于计算机硬件资源和软件资源。例如,服务器带宽是2Mb/s,某个资源的下载速度是1Mb/s,系统启动十个线程下载资源,下载速度也不会编程10M/s。也就是多,当达到2M带宽时,其他线程就处于等待状态了。
6 如何解决资源限制问题?
1、集群,单机有资源限制,那么就让程序在多机上运行。
2、资源复用,比如使用连接池将数据库连接复用