## 线程多线程基础了解
### 什么是线程,什么是多线程,线程和进程的区别,为什么要有多线程?
线程是cpu执行任务的最小单位
一个进程有1到n的线程组成,比如我们常用的编辑工具打开后就是一个进程,而这个进程就是由多个线程组成
### 为什么要有线程?
因为线程可以把执行时间长的任务交给后台处理,可以大大节省时间,使程序使用率大大提高
比如我们在处理一个业务时,有一个任务其实对返回结果没有影响,但是执行时间比较长又不得不处理,这里我们就可以用线程,把这个任务交给线程去执行,这样就大大节约了
时间提高了效率
### 既然有了线程为什么要有多线程呢?
因为有时候任务量太多,可能一个线程处理不过来,这样就可以用多个线程同时处理这样就可以提高效率
比如你开了家餐馆,那么客人来了肯定要做菜,但是你一个人肯定忙不过来,那么就请了两个伙计,一个伙计去买菜,一个伙计去做其他准备工作,你直接负责分配任务就好了,这样
任务就能快速完成
### 那么是不是线程越多,任务完成的就越快时间用的就越少呢?
答案是否定的,因为线程的执行是cpu分配的,当cpu时间分片分配到执行线程,从上个线程切换到另外一个线程这种上下文切换及启动线程是要花费时间的,这样资源都浪费到上下文切换
上面了,所以并不是线程越多就越好,得根据具体情况来
### 线程的实现方式
线程有两种一种是继承Thread类,一种是实现runnable接口 其实底层Thread类也是实现了Runnable接口
Thread
Thread t = new Thread();
t.start
Runnable
new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("无返回结果异步任务2");
}
}
线程的启动是start方法,而start()方法只在Thread中有,而Runnable接口只有一个run()方法
start()和run()的区别是什么?start方法是指线程启动,并不是运行,启动是指线程进入就绪状态,就比如百米赛跑都准备在起点线,
而run方法才是运行状态就是百米赛跑参赛者竞逐的阶段
### 线程的周期
新建new-》准备就绪runnable-》运行running-》运行完成(compalate)/阻塞(blocked)-》销毁
线程常用方法
start() 启动线程,等待cpu时间分片分配资源
run() 运行
sleep()休眠等待,但是线程是不会释放锁,锁会一直把持住,等休眠时间到了继续执行
wait()等待,与sleep不同的是,wait方法会释放锁释放资源,如果被唤醒后是进入就绪状态而非执行状态,需要等待cpu再次分配资源后才能运行
notify()唤醒 将等待的线程唤醒至就绪状态
yied()礼让使当前线程先暂停,让别的线程先执行
join()使线程让顺序执行
priority()可以设置线程优先级,这样cpu在分配资源的时候会把资源优先分配给优先级高的,但是不是绝对的
#### 那么现在有一个问题,比如我在执行某个方法的时候有两个线程A和B,我要保证A一定在B之前执行,怎么办?
这时我们可以用join方法,join方法就是保证了线程的执行顺序,可能也会有疑问可以设置优先级,但是这里是不行的,因为上面说了,优先级只能保证优先分配但不是绝对的
所以这里只能用join,因为join会阻塞线程,只有当线程执行完毕后才会继续像下面执行
为什么join会顺序执行,因为掉用join方法时,他底层是synchronize方法
只要你这个线程没有执行完毕,那么主线程就会无限的调用wait方法等待线程执行完成,直到你执行完毕为止,所以join可以保证线程的执行顺序,也解释了上面说的join会阻塞线程的原因
## 上面说了多个线程上下文切换或者一直新起线程会引起资源不必要的浪费有时候甚至可以导致程序的奔溃,那么有什么办法能避免这种浪费达到即能快速的执行任务又能保证资源的利用率呢
## 线程池是一个好东西,它既能保证线程的重复利用,也不会像上面所说的浪费那么多资源,这个下期在说
来源:https://www.cnblogs.com/zmblog/p/9686438.html