- ------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------
- 多线程的理解:
进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位.
线程是进程的实体,一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行.
一个程序至少有一个进程,一个进程至少有一个线程;每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
- 创建线程的方法:
第一种:
1.继承Thread类:子类覆盖父类中的run方法;
2.将线程的运行代码写在run方法中;
3.建立子类对象的同时线程也被创建;通过调用start方法开启线程。
ps:不建议此方法,因为如果一个类只是为了创建一个线程而去继承Thread类的话,那么就违背了java中继承的原理,只有当两个类之间有某种直接关系的时候才要去继承,千万不要为了调用某一个方法而去继承某一个类。
第二种:实现Runnable接口:
1.定义一个类实现Runnable接口;
2.然后覆盖其中的run方法,将线程要运行的代码放在run方法中;
3.通过Thread类建立线程对象;
4.将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数,因为自定义类的run方法所属的对象是Runnable接口的子类对象,所以要让线程去执行指定对象的的run方法,就必须明确该run方法所属的对象。
5.调用Thread类的start方法开启线程并杜鳌用Runable接口子类的run方法。
- 多线程运行的状态图:
- 多线程的安全问题:
cpu在同一时间,只能去执行一个线程,所以当一个2个线程在同时执行一段代码的时候,那么线程a得到了执行权,线程b在等待,线程a在执行一段代码的时候在中间停了下来,也就是cpu执行权到了线程b的手里,线程b也来执行这段代码,并且执行完,这时候线程a得到cpu执行权,继续执行刚才读到一半的代码,这个时候就会出现安全问题。
解决办法:
- synchronized同步代码块:
- 线程池的作用:
线程池作用就是限制系统中执行线程的数量。
根据系统的环境情况,可以自动或手动设置线程数量,达到运行的最佳效果;少了浪费了系统资源,多了造成系统拥挤效率不高。用线程池控制线程数量,其他线程排队等候。一个任务执行完毕,再从队列的中取最前面的任务开始执行。若队列中没有等待进程,线程池的这一资源处于等待。当一个新任务需要运行时,如果线程池中有等待的工作线程,就可以开始运行了;否则进入等待队列。
1.减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。
2.可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因为消耗过多的内存,而把服务器累趴下
- 四种线程池:
1. newSingleThreadExecutor
创建一个单线程的线程池。这个线程池只有一个线程在工作,也就是相当于单线程串行执行所有任务。如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。
2.newFixedThreadPool
创建固定大小的线程池。每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。
3. newCachedThreadPool
创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需要的线程,
那么就会回收部分空闲(60秒不执行任务)的线程,当任务数增加时,此线程池又可以智能的添加新线程来处理任务。此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统
4.newScheduledThreadPool
创建一个大小无限的线程池。此线程池支持定时以及周期性执行任务的需求