线程:
线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序,简而言之:一个程序运行后至少有一个进程,一个进程中可以包含多个线程,什么是线程呢?
即就是一个程序中有多个程序在同时执行。
单线程程序:例如,去网吧上网,网吧的一台只能让一个人上网,当这个人下机后,下一个人才能上网。
若有多个任务只能依次执行,当上一个任务执行结束后,下一个才开始执行
多线程程序:例如,去网吧上网,网吧能够让多个人同时上网
有多个任务可以同时执行
程序运行原理
分时调度:
所有线程轮流使用CPU的使用权,平均分配每个线程占用CPU的时间
抢占式调度:
优先让优先级高的线程使用CPU,如果线程的优先级相同,那么会随机选择一个(线程随机性),Java使用的为抢占式调用
实际上,CPU(中央处理器)使用抢占式调度模式在多个线程间进行着高速的切换,对于CPU的一个核而言,某个时刻,只能执行一个线程,而CPU在多个线程间切换速度相对我们的感觉要快,看上去就是同一时刻运行。
其实,多线程程序并不能提高程序的运行速度,但能够提高程序运行效率,让CPU的使用率更高
线程安全
如果有多个线程在同时运行,而这些线程可能会同时运行这段代码。程序每次运行结果和单线程运行的结果都是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的
同步方法:在方法声明上加synchronized
public synchronized void method(){
//可能会产生线程安全问题的代码
}
死锁
同步锁使用的弊端:当线程任务中出现了多个同步(多个锁)时,如果同步中嵌套了其他的同步,这时就容易引发一种现象,程序出现无限等待,这种现象我们称为死锁,这种情况能避免就避免掉。
synchronzied(A锁){
synchronized(B锁){ }
}
死锁案例:
public class DeadLock implements Runnable{
private int id;
//声明两个静态的引用类型对象
private static Object obj1 = new Object();
private static Object obj2 = new Object();
public DeadLock(int id) {
super();
this.id = id;
}
@Override
public void run() {
if(id == 1){
synchronized (obj1) {
try {
System.out.println("线程"+id+"已锁定obj1,等待锁定obj2");
Thread.sleep(1000);
synchronized (obj2) {
System.out.println("线程"+id+"执行结束");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}else{
synchronized (obj2) {
try {
System.out.println("线程"+id+"已锁定obj2,等待锁obj1");
Thread.sleep(1000);
synchronized (obj1) {
System.out.println("线程"+id+"执行结束");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
DeadLock d1 = new DeadLock(1);
DeadLock d2 = new DeadLock(2);
new Thread(d1).start();
new Thread(d2).start();
}
}