多线程
进程和线程的关系:
1.一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。
2.资源是分配给进程的,同一进程的所有线程共享该进程的所有资源
使用多线程的好处:
多线程可以提高程序的效率。
实例:寺庙里面没有水了,老和尚让小和尚去挑水,如果小和尚一个人去挑的话就需要跑四趟。但是小和尚请了他的三个伙伴老大,老二,老三帮忙,结果只需要跑一趟就可以完成任务了。
这个案例把每个和尚就是一个线程。
多线程的适合使用的场景:
1.一般线程之间比较独立,互不影响
2.一个线程发生问题,一般不影响其它线程
多线程的实现方式:
顺序编程:程序从上往下的同步执行,即如果第一行代码执行没有结束,第二行代码就只能等待第一行执行结束后才能结束。
并发编程:多个任务可以同时做,常用与任务之间比较独立,互不影响。
这里吃饭语句在喝酒语句前面,而运行结果是开始吃饭,开始喝酒,结束吃饭,结束喝酒,就是因为这是并发进行的,并发编程可以同时运行,而不必等前面的代码运行完之后才允许后面的代码
多线程的创建方式:
1.继承 Thread类
2.实现 Runable接口
备注:这里传的是同一个对象rt,表示共享资源的意思,只有多个线程访问共享的资源才会出现并发问题,如果是不同的对象,都不是共享的资源,也就不存在线程竞争并发问题了
3.实现 Callable接口
三者的区别:
Thread::继承方式, 不建议使用, 因为Java是单继承的,继承了Thread就没办法继承其它类了,不够灵活
Runnable::实现接口,比Thread类更加灵活,没有单继承的限制,但是run方法没有返回值
Callable:重写的call()方法并且有返回值并可以借助FutureTask类来判断线程是否已经执行完毕或者取消线程执行
线程的状态:
1.创建(new)状态: 准备好了一个多线程的对象,即执行了new Thread(); 创建完成后就需要为线程分配内存
2.就绪(runnable)状态: 调用了start()方法, 等待CPU进行调度
3.运行(running)状态: 执行run()方法
4.阻塞(blocked)状态: 暂时停止执行线程,将线程挂起(sleep()、wait()、join()、没有获取到锁都会使线程阻塞), 可能将资源交给其它线程使用
5.死亡(terminated)状态: 线程销毁(正常执行完毕、发生异常或者被打断interrupt()都会导致线程终止)