当前位置: 首页 > news >正文

做网站编辑需要看什么书wordpress 破解账号

做网站编辑需要看什么书,wordpress 破解账号,平顶山企业网站建设,直播间 网站建设目录 一、多线程 1. 概述 2. 进程与线程 2.1 程序 2.2 进程 2.3 线程 2.4 进程与线程的区别 3. 线程基本概念 4.并发与并行 5. 线程的创建方式 方式一#xff1a;继承Thread类 方式二#xff1a;实现Runable接口 方式三#xff1a;实现Callable接口 方式四…目录 一、多线程 1. 概述 2. 进程与线程 2.1 程序 2.2 进程 2.3 线程 2.4 进程与线程的区别 3. 线程基本概念 4.并发与并行 5. 线程的创建方式 方式一继承Thread类 方式二实现Runable接口 方式三实现Callable接口 方式四线程池 小结: 二、ThreadMethod  1. Thread类常用的构造方法 2. 线程的命名  3. 获取当前线程 4. 线程的休眠暂停 5. 线程的优先级 6. 守护线程Daemon Thread 用户线程与守护线程的区别 设置守护线程 7. 线程的让出yield( )方法 8. 线程的插队join( )方法  9. 小结 三、线程安全问题 多线程售票问题 解决方案1 解决方案2 解决方案3 四、线程状态 1. New新建状态 2. Runnable运行状态 3. Terminated终止状态 4. Blocked阻塞状态 5. Timed Waiting计时等待状态 6.  Waiting等待状态 五、线程池 1. 什么是线程池 2. 线程池常用类和接口 3. 线程池常见方法 执行线程任务 4. 线程池分类总结 FixedThreadPool CachedThreadPool SingleThreadExecutor ScheduledThreadPool 5. 线程池的配置参数 6. 线程池的执行流程 7. 线程池的状态 一、多线程 1. 概述 现代操作系统WindowsmacOSLinux都可以执行多任务。多任务就是同时运行多个任务。例如播放音乐的同时浏览器可以进行文件下载同时可以进行QQ消息的收发。 CPU执行代码都是一条一条顺序执行的但是即使是单核CPU也可以同时运行多个任务。因为操作系统执行多任务实际上就是让CPU对多个任务轮流交替执行。 操作系统轮流让多个任务交替执行例如让浏览器执行0.001秒让QQ执行0.001秒再让音乐播放器执行0.001秒。在用户使用的体验看来CPU就是在同时执行多个任务。 2. 进程与线程 2.1 程序 程序是含有指令和数据的文件被存储在磁盘或其他的数据存储设备中可以理解为程序是包含静态代码的文件。例如浏览器软件、音乐播放器软件等软件的安装目录和文件。 2.2 进程 进程是程序的一次执行过程是系统运行程序的基本单位。在Windows系统中每一个正在执行的exe文件或后台服务都是一个进程由操作系统统一管理并分配资源因此进程是动态的。 例如正在运行中的浏览器就是一个进程正在运行中的音乐播放器是另一个进程同理正在运行中的QQ和WPS等都是进程。操作系统运行一个程序即是一个进程从创建运行到消亡的过程。简单来说一个进程就是一个执行中的程序它在计算机中一个指令接着一个指令地执行着 同时每个进程还占有某些系统资源如 CPU时间内存空间文件输入输 出设备的使用权等。 2.3 线程 某些进程内部还需要同时执行多个子任务。例如我们在使用WPS时WPS可以让我们一边打字一边进行拼写检查同时还可以在后台进行自动保存和上传云文档我们把子任务称为线程。线程是进程划分成的更小的运行单位。进程和线程的关系就是一个进程可以包含一个或多个线程但至少会有一个主线程。 2.4 进程与线程的区别 根本区别进程是操作系统资源分配的基本单位而线程是处理器任务调度和执行的基本单位资源开销每个进程都有独立的代码副本和数据空间进程之间的切换资源开销较大线程可以看做轻量级的进程每个线程都有自己独立的运行栈和程序计数器线程之间切换资源开销小包含关系一个进程内包含有多个线程在执行过程线程的执行不是线性串行的而是多条线程并行共同完成内存分配同一进程内的所有线程共享本进程的内存空间和资源进程之间的内存空间和资源相互独立影响关系一个进程崩溃后在保护模式下不会对其他进程产生影响一个线程崩溃会导致整个进程退出。所以多进程要比多线程健壮执行过程每个独立的进程有程序运行的入口和程序出口。但是线程不能独立执行必须依存在应用程序进程中由应用程序提供多个线程执行控制 3. 线程基本概念 单线程单线程就是进程中只有一个线程。单线程在程序执行时所走的程序路径按照连续顺序排下来前面的必须处理好后面的才会执行。 public static void main(String[] args) {int a 10;int b 20;int cab;System.out.println(c);} 多线程由一个以上的线程组成的程序称为多线程程序。Java中一定是从主线程开始执行main方法然后在主线程的某个位置创建并启动新的线程。 作用最主要是为了提高程序的运行效率 多线程应用场景软件中耗时的操作  拷贝,迁移文件,加载大量的时候 为什么要有多线程线程:操作系统能够进行调度的最小单元,他被包含在进程中,是进程中实际运行的单位 进程:进程是程序的基本执行实体 4.并发与并行 并发:在同一时刻,有多个指令在单个Cpu上交替执行并行:在同一时刻,有多个指令在单个Cpu上同时执行 5. 线程的创建方式 方式一继承Thread类 继承 java.lang.Thread 类线程子类 创建多线程的方法1: 自定义一个类继承Thread重写run方法创建子类的对象,并启动线程  MyThread类 public class MyThread extends Thread {public MyThread() {super();}Overridepublic void run() {//写线程要执行的代码for (int i 0; i 100; i) {System.out.println(getName()_hello);}} } Demo01类 public class Demo01 {public static void main(String[] args) {/***创建多线程的方法1:*1.自定义一个类继承Thread*2.重写run方法*3.创建子类的对象,并启动线程*/MyThread t1 new MyThread();t1.setName(线程1);//给线程设置名称t1.start();//此处需要注意,不能直接调用run方法,否则就是对象的创建和方法的调用MyThread t2 new MyThread();t2.setName(线程2);t2.start();for (int i 0; i 15; i) {System.out.println(Thread.currentThread().getName()_world);}} } 方式二实现Runable接口 实现 java.lang.Runnable 接口线程执行类 创建多线程的方法2: 自己定义一个类实现Runable接口重写里面的run方法创建自己的类的对象创建Thread类的对象,并开启线程 MyRun类 public class MyRun implements Runnable {Overridepublic void run() {// 写线程要执行的代码for (int i 0; i 100; i) {System.out.println(Thread.currentThread().getName() _hello);}} } Demo02类 public class Demo02 {public static void main(String[] args) {/*** 1.自己定义一个类实现Runable接口 2.重写里面的run方法 3.创建自己的类的对象 4.创建Thread类的对象,并开启线程*/// 创建MyRun多线程,标识多线程要执行的任务MyRun run new MyRun();// 创建线程Thread t1 new Thread(run);Thread t2 new Thread(run);t1.setName(线程1);t2.setName(线程2);t1.start();t2.start();} } 方式三实现Callable接口 实现 java.util.concurrent.Callable 接口允许子线程返回结果、抛出异常 创建多线程的方法3: 创建Callable是实现类重写ca11方法 创建Mycal1实现类的对象 创建FutureTask的对象(管理多线程运行的结果)创建Thread对象,并启动 MyCall类 public class MyCall implements CallableInteger{//求1-100之间的和Overridepublic Integer call() throws Exception {int sum 0;for (int i 1; i 100; i) {sumi;}return sum;}} Demo03类 public class Demo03 {public static void main(String[] args) throws InterruptedException, ExecutionException {/*** 1.创建Callable是实现类* 2.重写ca11方法 * 3.创建Mycal1实现类的对象 * 4.创建FutureTask的对象(管理多线程运行的结果)* 5.创建Thread对象,并启动*/MyCall call1 new MyCall();FutureTaskInteger ft new FutureTaskInteger(call1);Thread t1 new Thread(ft);t1.start();//获取多线程运行后的结果Integer result ft.get();System.out.println(result); 方式四线程池 线程池见五、线程池 小结: 继承Thread类           优点编程比较简单,可以直接使用Thread类中的方法,       缺点可扩展性比较差,不能再继承其他的类实现Runable接口     优点扩展性强,实现该接口后还可以同时继承其他类,实现其他的接口     缺点编程相对比较复杂,不能直接使用Thread类中的方法实现Callable接口     优点有返回值,可以利用FutureTask进行结果的保存           缺点编程相对比较复杂,不能直接使用Thread类中的方法        注意直接调用Thread实例的run()方法是无效的因为直接调用run()方法相当于调用了一个普通的Java方法当前线程并没有任何改变也不会启动新线程。                          二、ThreadMethod  1. Thread类常用的构造方法 public class MyThread extends Thread {public MyThread() {super();}public MyThread(String name) {super(name);}Overridepublic void run() {for (int i 0; i 20; i) {try {sleep(100);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println(getName() i);}} } Thread类常用的构造方法: Thread() Thread(String name) Thread(Runnable run,String name, Thread(Runnable run) MyThread t1 new MyThread(); // 通过构造方法创建线程MyThread t2 new MyThread(线程2); 2. 线程的命名  生产环境中为了排查问题方便建议在创建线程的时候指定一个合理的线程名字 调用父类的setName()方法或在构造方法中给线程名字赋值 // getName():获取线程名称// 细节:如果给线程没有设置名称,线程也有默认的名称 Thread-x(从0开始)// setName()设置线程的名称构造方法也可以设置线程的名称MyThread t1 new MyThread();t1.setName(线程1); 如果没有为线程命名系统会默认指定线程名命名规则是Thread-N的形式 3. 获取当前线程 Thread.currentThread() // Thread.currentThread()获取当前线程对象Thread tmain Thread.currentThread();tmain.setName(核心线程);for (int i 0; i 20; i) {System.out.println(tmain.getName() i);} 4. 线程的休眠暂停 在线程中可以通过调用Thread.sleep(long millis)强迫当前线程按照指定毫秒值休眠。 public class Main {public static void main(String[] args) {System.out.println(main start...);Thread t new Thread() {public void run() {System.out.println(thread run...);try {Thread.sleep(10); // 子线程休眠10毫秒} catch (InterruptedException e) {}System.out.println(thread end.);}};t.start();try {Thread.sleep(20); // 主线程休眠20毫秒} catch (InterruptedException e) {}System.out.println(main end...);} } 5. 线程的优先级 在线程中通过setPriority(int n)设置线程优先级范围是1-10默认为 5优先级高的线程被操作系统调度的优先级较高操作系统对高优先级线程调度更频繁注意并不能代表通过设置优先级来确保高优先级的线程一定会先执行案例 public static void main(String[] args) {//创建一个匿名内部类对象runRunnable run new Runnable() {Overridepublic void run() {for (int i 0; i 20; i) {System.out.println(Thread.currentThread().getName() i);}}};Thread t1 new Thread(run, 线程1);Thread t2 new Thread(run, 线程2);//获取线程的优先级默认为5System.out.println(t1.getPriority());System.out.println(线程t2的优先级为 t2.getPriority());System.out.println(主的优先级为 Thread.currentThread().getPriority());//设置优先级优先级的取值范围1-10之间优先级越高抢到的线程概率越大但并不是绝对的t1.setPriority(10);t2.setPriority(1);t1.start();t2.start();} 6. 守护线程Daemon Thread 用户线程与守护线程的区别 用户线程我们平常创建的普通线程守护线程用来服务于用户线程的线程在JVM中所有非守护线程都执行完毕后无论有没有守护线程虚拟机都会自动退出而守护线程执行结束后虚拟机不会自动退出。 设置守护线程 守护线程:备胎线程--setDaemon(true)         细节:当其他的非守护的线程执行完毕后守护线程会陆续结束         即(当女神线程结束那么备胎线程也没有存在的必要) 在调用start()方法前调用setDaemon(true)把该线程标记为守护线程 public static void main(String[] args) {//守护线程:备胎线程--setDaemon(true)//细节:当其他的非守护的线程执行完毕后守护线程会陆续结束//即(当女神线程结束那么备胎线程也没有存在的必要)//创建线程1Thread t1 new Thread() {Overridepublic void run() {for (int i 1; i 10; i) {System.out.println(getName()i);}};};//创建线程2Thread t2 new Thread() {Overridepublic void run() {for (int i 1; i 100; i) {System.out.println(getName()i);}};};//给线程设置名称t1.setName(女神);t2.setName(备胎);//将第二个线程设置为守护线程t2.setDaemon(true);t1.start();t2.start();} 7. 线程的让出yield( )方法 线程通过调用yield()方法告诉JVM的线程调度当前线程愿意让出CPU给其他线程使用。 ○至于系统是否采纳取决于JVM的线程调度模型分时调度模型和抢占式调度模型 分时调度模型所有的线程轮流获得 cpu的使用权,并且平均分配每个线程占用的 CPU 时间片抢占式调度模型优先让可运行池中优先级高的线程占用 CPU如果可运行池中的线程优先级相同那么就随机选择一个线程使其占用CPU。JVM虚拟机采用的是抢占式调度模型 public class MyThread1 extends Thread {//当前线程让出执行权后再次进行抢夺也可能会抢夺到相关资源Overridepublic void run() {for (int i 1; i 100; i) {System.out.println(getName() i);//表示让出当前的cpu的执行权会让结果更加均匀一点但是并非绝对Thread.yield();//出让线程礼让线程}} } public class Demo04 {public static void main(String[] args) {//创建线程1和线程2//出让线程礼让线程Thread.yield();MyThread1 t1 new MyThread1();MyThread1 t2 new MyThread1();t1.setName(线程1);t2.setName(线程2);t1.start();t2.start();} } 8. 线程的插队join( )方法  t.join()方法会使当前线程( 主线程 或者调用t.join()的线程 )进入等待池并等待 线程t 执行完毕后才会被唤醒。此时并不影响同一时刻处在运行状态的其他线程。 public class Demo05 {public static void main(String[] args) throws InterruptedException {//线程对象.join();插队线程//此时土豆线程会和main线程抢占cpu的资源//如果土豆先执行后执行main就用到join方法MyThread2 t1 new MyThread2();t1.setName(土豆);t1.start();//表示把t1线程插入到当前的线程前面t1.join();for (int i 0; i 100; i) {System.out.println(Thread.currentThread().getName()i);}} }class MyThread2 extends Thread {Overridepublic void run() {for (int i 1; i 100; i) {System.out.println(getName() i);}} }9. 小结 Thread线程的方法 getName()--有默认的线程名setName()--给线程设置名称,构造方法也可以设置线程名Thread.currentThread(),获取当前线程getPriority() 获取线程的优先级1-10,默认的优先级为5setPriority(int) 数字越大优先级越大sleep(long mill)   睡眠join()  插队线程yield() 礼让线程setDaemon(boolean) 守护线程 三、线程安全问题 多线程售票问题 public class MyThread extends Thread {//表示当前的变量提升到了类级别所有的类共享此成员变量static int ticket 0;Overridepublic void run() {// 卖票while (true) {if (ticket 10) {try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}ticket;System.out.println(getName() 正在卖出第 ticket 张票);} else {break;}}} }public class Demo01 {public static void main(String[] args) {//线程在进行执行的过程中cpu的执行权随时都可能被其他线程给抢走MyThread t1 new MyThread();MyThread t2 new MyThread();MyThread t3 new MyThread();t1.setName(窗口1);t2.setName(窗口2);t3.setName(窗口3);//线程启动开始卖票t1.start();t2.start();t3.start();} } 当多个线程同时运行时线程的调度由操作系统决定程序本身无法决定。因此任何一个线程都有可能在任何指令处被操作系统暂停然后在某个时间段后继续执行。 这个时候一个在单线程模型下不存在的问题就会发生如果多个线程同时读写共享变量会出现数据不一致的问题。 解决方案1 解放方案1:锁代码块: synchronized(锁对象){//锁对象可以是任意类型对象但是必须要保证多个线程使用同一个锁操作的共享的数据资源} 默认下锁是打开装填有一个线程进来锁自动关闭 里面的代码执行完毕线程出来锁自动打开 public class MyThread extends Thread {// 表示当前的变量提升到了类级别所有的类共享此成员变量static int ticket 0;//注意事项:锁对象要唯一static Object obj new Object();Overridepublic void run() {// 卖票while (true) {synchronized (obj) {if (ticket 1000) {try {Thread.sleep(100);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}ticket;System.out.println(getName() 正在卖出第 ticket 张票);} else {break;}}}} }解决方案2 解放方案2:锁方法: 修饰符 synchronized 返回值类型 方法名(){括号内写的是共享的资源 } 1.特点:同步方法锁锁住的方法中的代码 2.特点:方法上面的锁不能自己指定,             实例方法:通过当前对象,作为“锁”             静态方法:通过当前类class字节码对象作为“锁 public class MyThread extends Thread {// 表示当前的变量提升到了类级别所有的类共享此成员变量static int ticket 0;Overridepublic void run() {// 卖票while (true) {if (Method()) {break;}}}public static synchronized boolean Method() {if (ticket 100) {try {Thread.sleep(100);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}ticket;System.out.println(Thread.currentThread().getName() 正在卖出第 ticket 张票);} else {return true;}return false;} } public class Demo02 {public static void main(String[] args) {//MyRun作为Thread线程的参数进行传值MyRun run new MyRun();Thread t1 new Thread(run,线程1);Thread t2 new Thread(run,线程2);Thread t3 new Thread(run,线程3);t1.start();t2.start();t3.start();} } class MyRun implements Runnable{static int ticket 0;Overridepublic void run() {while (true) {if (Method()) {break;}}}//此处锁对象为当前的对象public static synchronized boolean Method() {if (ticket 10000) {try {Thread.sleep(100);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}ticket;System.out.println(Thread.currentThread().getName() 正在卖出第 ticket 张票);} else {return true;}return false;} } 解决方案3 解放方案3:Lock锁  1.5: 可以手动开锁关锁 lock();加锁 unlock();解锁 //Lock锁 1.5 //可以手动开锁关锁 //lock();加锁 //unlock();解锁public class MyThread extends Thread {// 表示当前的变量提升到了类级别所有的类共享此成员变量static int ticket 0;static Lock lock new ReentrantLock();Overridepublic void run() {while (true) {lock.lock();try {if (ticket 100) {ticket;System.out.println(getName() 正在卖出第 ticket 张票);} else {break;}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}finally {lock.unlock();}}}} 四、线程状态 在Java程序中一个线程对象通过调用start()方法启动线程并且在线程获取CPU时自动执行run()方法。run()方法执行完毕代表线程的生命周期结束。●在整个线程的生命周期中线程的状态有以下6种 New新建状态新创建的线程此时尚未调用start()方法Runnable运行状态运行中的线程已经调用start()方法线程正在或即将执行run()方法Blocked阻塞状态运行中的线程在等待竞争锁时被阻塞暂不执行Waiting等待状态运行中的线程因为join()等方法调用进入等待Timed Waiting计时等待状态运行中的线程因为执行sleep(等待毫秒值)join(等待毫秒值)等方法进入计时等待Terminated终止状态线程已终止因为run()方法执行完毕。 ●当线程启动后它可以在Runnable、Blocked、Waiting和Timed Waiting这几个状态之间切换直到最后变成Terminated状态线程终止 线程终止的原因有 ○线程正常终止run()方法执行到return语句返回 ○线程意外终止run()方法因为未捕获的异常导致线程终止 ○对某个线程的Thread实例调用stop()方法强制终止宇宙超级无敌强烈不推荐 1. New新建状态 新建状态:线程对象创建还没有调用start方法的时候 //新建状态:线程对象创建还没有调用start方法的时候 public class NewState {public static void main(String[] args) {Thread thread new Thread() {Overridepublic void run() {System.out.println(正在执行某件任务);};};System.out.println(thread.getState());//NEW} } 2. Runnable运行状态 线程对象调用start()方法处于等待CPU分配资源running ready //线程对象调用start()方法处于等待CPU分配资源running ready public class RunState {public static void main(String[] args) {Thread thread new Thread() {Overridepublic void run() {System.out.println(正在执行某件任务);};};thread.start();System.out.println(thread.getState());// RUNNABLE} } 3. Terminated终止状态 TERMINATED操作系统注销此 //TERMINATED操作系统注销此 public class TerminatedState {public static void main(String[] args) throws InterruptedException {Thread thread new Thread() {Overridepublic void run() {System.out.println(正在执行某件任务);};};thread.start();Thread.sleep(1000);System.out.println(thread.getState());//TERMINATED} } 4. Blocked阻塞状态 运行中的线程在等待竞争锁时被阻塞暂不执行 public class BlockedState {public static void main(String[] args) throws InterruptedException {Runnable run new Runnable() {Overridepublic void run() {synchronized (this) {//死循环while (true);}}};//创建线程t1和t2,并启动线程Thread t1 new Thread(run, t1);Thread t2 new Thread(run, t2);t1.start();t2.start();//让主线程睡眠1秒目的想让t1和t2同时竞争一个锁Thread.sleep(1000);System.out.println(t1 state t1.getState());System.out.println(t2 state t2.getState());} } 5. Timed Waiting计时等待状态 运行中的线程因为执行sleep(等待毫秒值)join(等待毫秒值)等方法进入计时等待 // wait() // notify() // notifyA11() //注意事项: //1.要和synchronized写在一起 //2.锁对象要和调用的对象保持一致//TIMED WAITING计时等待 //执行sleep(1ong millis)等方法 不会释放锁资源 //执行wait(long millis)等方法 会释放所资源 // join(等待时间) public class TimeWaitingState {public static void main(String[] args) throws InterruptedException {Runnable run new Runnable() {Overridepublic void run() {synchronized (this) {System.out.println(Thread.currentThread().getName());try { // Thread.sleep(5000);this.wait(5000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}};Thread t1 new Thread(run, t1);Thread t2 new Thread(run, t2);// 期待线程观察sleep方法和wait方法对比t1.start();t2.start();// 让当前线程睡眠1秒Thread.sleep(1000);// 获取线程状态System.out.println(t1.getState());System.out.println(t2.getState());} } //Object 类 // wait(long) // wait()//TIMED WAITING计时等待 //执行sleep(long millis)等方法 不会释放锁资源 //执行wait(long millis)等方法 会释放所资源 //执行 join(等待时间) public class TimeWaitingState02 {public static void main(String[] args) throws InterruptedException {Thread thread new Thread() {Overridepublic void run() {Thread t1 new Thread() {Overridepublic void run() {System.out.println(t1线程);};};t1.start();//join方法会让当前的线程处于计时等待try {t1.join(500 * 1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}};};thread.start();Thread.sleep(1000);//查看thread线程的状态System.out.println(thread.getState());} } 6.  Waiting等待状态 运行中的线程因为join()等方法调用进入等待 //WAITING 等待状态 wait() // join()//Oject中的wait() wait(long time) //1.synchronized写在一起 //2.锁对象要和调用的对象保持一致 public class WaitingState01 {public static void main(String[] args) throws InterruptedException {Object obj new Object();Thread t1 new Thread() {public void run() {synchronized (obj) {try {obj.wait();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}};};t1.start();Thread.sleep(1000);System.out.println(t1.getState());//WAITING} } //Oject中的wait() wait(long time) // 1.synchronized写在一起 // 2.锁对象要和调用的对象保持一致 public class WaitingState02 {public static void main(String[] args) throws InterruptedException {Thread t1 new Thread() {Overridepublic void run() {while (true);}};t1.start();t1.join();//t1加到当前的主线程的前面主线程一直处于等待状态//获取不到因为当前的主线程被t1线程插队,t1线程任务是个死循环无法结束System.out.println(Thread.currentThread().getState());} }五、线程池 1. 什么是线程池 线程池内部维护了若干个线程没有任务的时候这些线程都处于等待空闲状态。如果有新的线程任务就分配一个空闲线程执行。如果所有线程都处于忙碌状态线程池会创建一个新线程进行处理或者放入队列工作队列中等待。 线程池线程池是一个可以复用线程的技术 2. 线程池常用类和接口 在Java标准库提供了如下几个类或接口来操作并使用线程池 ExecutorService接口进行线程池的操作访问Executors类创建线程池的工具类ThreadPoolExecutor及其子类封装线程池的核心参数和运行机制 MyRunable类 public class MyRunable implements Runnable {public MyRunable() {}public MyRunable(String name) {}Overridepublic void run() {// TODO Auto-generated method stub}} 线程池的基本使用方式 //线程池线程池是一个可以复用线程的技术 //1. ExecutorService接口进行线程池的操作访问 // submit() // execute() //2. Executors类创建线程池的工具类 // Executors.newCachedThreadPool() 创建一个线程没有上线的线程池 //3. ThreadPoolExecutor及其子类封装线程池的核心参数和运行机制 public class Demo01 {public static void main(String[] args) throws InterruptedException {// 创建一个线程没有上限的线程池ExecutorService pool1 Executors.newCachedThreadPool();// 线程池提交任务pool1.execute(new MyRunable()); // Thread.sleep(1000);pool1.execute(new MyRunable()); // Thread.sleep(1000);pool1.execute(new MyRunable()); // Thread.sleep(1000);pool1.execute(new MyRunable());// 销毁线程--用完后线程池给砸了pool1.shutdown();}} 3. 线程池常见方法 执行无返回值的线程任务void execute(Runnable command);提交有返回值的线程任务FutureT submit(CallableT task);关闭线程池void shutdown(); 或 shutdownNow();等待线程池关闭boolean awaitTermination(long timeout, TimeUnit unit); 执行线程任务         execute()只能提交Runnable类型的任务没有返回值而submit()既能提交Runnable类型任务也能提交Callable类型任务可以返回Future类型结果用于获取线程任务执行结果。         execute()方法提交的任务异常是直接抛出的而submit()方法是捕获异常当调用Future的get()方法获取返回值时才会抛出异常。 //线程池线程池是一个可以复用线程的技术 //1. ExecutorService接口进行线程池的操作访问 // submit()--提交任务 Runable Callable // execute()--提交任务Runable //2. Executors类创建线程池的工具类 // Executors.newCachedThreadPool() 创建一个线程没有上限的线程池 // Executors.newFixedThreadPool(int nThreads) 创建一个有上限的线程池 //3. ThreadPoolExecutor及其子类封装线程池的核心参数和运行机制public class Demo02 {public static void main(String[] args) { // Executors.newFixedThreadPool(int nThreads) 创建一个有上限的线程池ExecutorService pool Executors.newFixedThreadPool(5);pool.submit(new MyRunable(任务1));pool.submit(new MyRunable(任务2));pool.submit(new MyRunable(任务3));pool.submit(new MyRunable(任务4));}} MyCallable类 public class MyCallable implements CallableInteger{private int number;public MyCallable(int number) {this.number number;}Overridepublic Integer call() throws Exception {int sum 0;for (int i 0; i number ; i) {sumi;}return sum;}} //线程池线程池是一个可以复用线程的技术 //1. ExecutorService接口进行线程池的操作访问 // submit()--提交任务 Runable Callable // execute()--提交任务Runable //2. Executors类创建线程池的工具类 // Executors.newCachedThreadPool() 创建一个线程没有上线的线程池 // Executors.newFixedThreadPool(int nThreads) 创建一个有上线的线程池 // 核心线程数量到底配置多少计算密集型任务: CPU的核数1; IO密集型任务: CPU的核数*2 //3. ThreadPoolExecutor及其子类封装线程池的核心参数和运行机制public class Demo03 {public static void main(String[] args) throws InterruptedException, ExecutionException {// 创建一个有上线的线程的线程池ExecutorService pool Executors.newFixedThreadPool(5);//测试submit的方法--传callable值FutureInteger futureTask1 pool.submit(new MyCallable(10));FutureInteger futureTask2 pool.submit(new MyCallable(100));FutureInteger futureTask3 pool.submit(new MyCallable(1000));System.out.println(futureTask1.get());//55System.out.println(futureTask2.get());//5050System.out.println(futureTask3.get());//500500}} 4. 线程池分类总结 FixedThreadPool 线程数固定的线程池 线程池参数 核心线程数和最大线程数一致非核心线程线程空闲存活时间即keepAliveTime为0阻塞队列为无界队列LinkedBlockingQueue 工作机制 提交线程任务如果线程数少于核心线程创建核心线程执行任务如果线程数等于核心线程把任务添加到LinkedBlockingQueue阻塞队列如果线程执行完任务去阻塞队列取任务继续执行 使用场景 适用于处理CPU密集型的任务确保CPU在长期被工作线程使用的情况下尽可能的少的分配线程即适用执行长期的任务。 CachedThreadPool 可缓存线程池线程数根据任务动态调整的线程池线程池参数 核心线程数为0最大线程数为Integer.MAX_VALUE工作队列是SynchronousQueue同步队列非核心线程空闲存活时间为60秒 ●工作机制 提交线程任务因为核心线程数为0所以任务直接加到SynchronousQueue工作队列判断是否有空闲线程如果有就去取出任务执行如果没有空闲线程就新建一个线程执行执行完任务的线程还可以存活60秒如果在这期间接到任务可以继续存活下去否则被销毁。 使用场景 用于并发执行大量短期的小任务。 SingleThreadExecutor 单线程化的线程池线程池参数 核心线程数为1最大线程数也为1阻塞队列是LinkedBlockingQueue非核心线程空闲存活时间为0秒 使用场景 适用于串行执行任务的场景将任务按顺序执行。 ScheduledThreadPool 能实现定时、周期性任务的线程池线程池参数 最大线程数为Integer.MAX_VALUE阻塞队列是DelayedWorkQueuekeepAliveTime为0 使用场景 周期性执行任务并且需要限制线程数量的需求场景。 //线程池线程池是一个可以复用线程的技术 //1. ExecutorService接口进行线程池的操作访问 // submit() // execute() //2. Executors类创建线程池的工具类 // Executors.newCachedThreadPool() 创建一个线程没有上线的线程池如果任务执行完线程空闲60秒会被回收 // Executors.newFixedThreadPool(int nThreads) 创建一个有上线的线程池 // Executors.newSingleThreadExecutor()创建一个只有一个线程的线程池对象 // Executors.newScheduledThreadPool() 创建一个线程池可以实现在给时间延后执行或者定期执行任务 //3. ThreadPoolExecutor及其子类封装线程池的核心参数和运行机制public class Demo04 {public static void main(String[] args) { // 创建只有一个线程的线程池 // ExecutorService poolExecutors.newSingleThreadExecutor(); // pool.submit(new MyRunable(任务1)); // pool.submit(new MyRunable(任务2));//1.创建任务调度线程池对象ScheduledExecutorService pool1Executors.newScheduledThreadPool(2);Runnable run new Runnable() {Overridepublic void run() {System.out.println(Thread.currentThread().getName());}};//提交任务延时5秒执行 // pool1.schedule(run,5,TimeUnit.SECONDS);//提交任务延时5秒以后每1秒执行1次pool1.scheduleAtFixedRate(run, 5, 1,TimeUnit.SECONDS);}} 5. 线程池的配置参数 ●corePoolSize线程池核心线程数也可以理解为线程池维护的最小线程数量核心线程创建后不会被回收。大于核心线程数的线程在空闲时间超过keepAliveTime后会被回收 在创建了线程池后默认情况下线程池中并没有任何线程当调用 execute() 方法添加一个任务时如果正在运行的线程数量小于corePoolSize则马上创建新线程并运行这个任务。IO密集计算由于 I/O 设备的速度相对于 CPU来说都很慢所以大部分情况下I/O 操作执行的时间相对于 CPU 计算来说都非常长这种场景我们一般都称为 I/O 密集型计算。最佳线程数 CPU 核数 * [ 1 I/O 耗时 / CPU 耗时]。CPU密集型CPU 密集型计算大部分场景下都是纯 CPU 计算多线程主要目的是提升CPU利用率最佳线程数 “CPU 核心数 1”。这样的话当线程因为偶尔的内存页失效或其他原因导致阻塞时这个额外的线程可以临时替补从而保证 CPU 的利用率。 ●maximumPoolSize线程池最大线程数线程池允许创建的最大线程数量包含核心线程池数量●keepAliveTime非核心线程线程存活时间当一个可被回收的线程的空闲时间大于keepAliveTime就会被回收。 当线程池中的线程数大于corePoolSize时如果一个线程空闲的时间达到keepAliveTime则会被回收直到线程池中的线程数不超过corePoolSize。如果设置allowCoreThreadTimeOut true在线程池中的线程数不大于corePoolSize时keepAliveTime参数也会起作用直到线程池中的线程数为0 ●TimeUnit时间单位参数keepAliveTime的时间单位 ●BlockingQueue阻塞工作队列用来存储等待执行的任务 ●ThreadFactory线程工厂 : 用于创建线程以及自定义线程名称需要实现ThreadFactory接口 ●RejectedExecutionHandler拒绝策略当线程池线程内的线程耗尽并且工作队列达到已满时新提交的任务将使用拒绝策略进行处理 ThreadPoolExecutor.AbortPolicy默认策略丢弃任务并抛出RejectedExecutionException异常ThreadPoolExecutor.DiscardPolicy丢弃任务但是不抛出异常ThreadPoolExecutor.DiscardOldestPolicy丢弃工作队列中的队头任务即最旧的任务也就是最早进入队列的任务后继续将当前任务提交给线程池ThreadPoolExecutor.CallerRunsPolicy由原调用线程处理该任务 谁调用谁处理 MyRun 类: public class MyRun implements Runnable {private String name;public MyRun() {}public MyRun(String name) {this.name name;}Overridepublic void run() {System.out.println(Thread.currentThread().getName() name 正在执行);// 让任务稍微慢点便于观察结果try {Thread.sleep(Integer.MAX_VALUE);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}//线程池的创建方式2 // new ThreadPoolExecutorpublic class Demo01 {public static void main(String[] args) { // corePoolSize:线程核心数量 // maximumPoolSize:线程池中最大的线程数 // keepAliveTime临时线程的存活时间 // unit,时间单位(时分秒) // workQueue, 任务队列 // threadFactory, 为线程池创建线程的线程工厂 // handler:指定线程池的拒绝策略 // 1.AbortPolicy--丢弃任务并抛出异常默认拒绝策略 // 2.CallerRunsPolicy--由主线程负责调用run方法绕过线程池 // 3.DiscardOldestPolicy--抛弃队列中等待最久的任务把当前的任务加入到队列 // 4.DiscardPolicy--丢弃任务不抛出异常不推荐ExecutorService pool new ThreadPoolExecutor(3, 6, 60, TimeUnit.SECONDS, new ArrayBlockingQueueRunnable(3),Executors.defaultThreadFactory(), new ThreadPoolExecutor.DiscardPolicy());// MyRun run new MyRun();pool.execute(new MyRun(任务1));//提交第一个任务线程池会自动创建一个新的线程自动处理任务pool.execute(new MyRun(任务2));pool.execute(new MyRun(任务3));pool.execute(new MyRun(任务4));//提交第4个任务时候,进入等待队列中pool.execute(new MyRun(任务5));pool.execute(new MyRun(任务6));pool.execute(new MyRun(任务7));//提交第7个任务的时候核心线程数已满队列已满再来新任务看临时工pool.execute(new MyRun(任务8));//pool.execute(new MyRun(任务9));pool.execute(new MyRun(任务10));//核心线程满队列满临时满pool.execute(new MyRun(任务11));}} //线程池的创建方式2 // new ThreadPoolExecutorpublic class Demo02 {public static void main(String[] args) throws InterruptedException, ExecutionException { // corePoolSize:线程核心数量 // maximumPoolSize:线程池中最大的线程数 // keepAliveTime临时线程的存活时间 // unit,时间单位(时分秒) // workQueue, 任务队列 // threadFactory, 为线程池创建线程的线程工厂 // handler:指定线程池的拒绝策略 // 1.AbortPolicy--丢弃任务并抛出异常默认拒绝策略 // 2.CallerRunsPolicy--由主线程负责调用run方法绕过线程池 // 3.DiscardOldestPolicy--抛弃队列中等待最久的任务把当前的任务加入到队列 // 4.DiscardPolicy--丢弃任务不抛出异常不推荐ExecutorService pool new ThreadPoolExecutor(3, 6, 60, TimeUnit.SECONDS, new ArrayBlockingQueueRunnable(3),Executors.defaultThreadFactory(), new ThreadPoolExecutor.DiscardPolicy());FutureInteger f1pool.submit(new MyCall(10));FutureInteger f2pool.submit(new MyCall(20));FutureInteger f3pool.submit(new MyCall(30));System.out.println(f1.get());System.out.println(f2.get());System.out.println(f3.get());} }class MyCall implements CallableInteger {private int number;public MyCall(int number) {this.number number;}Overridepublic Integer call() throws Exception {int sum 0;for (int i 0; i number; i) {sum i;}return sum;}}public class Demo03 {public static void main(String[] args) { // corePoolSize:线程核心数量 // maximumPoolSize:线程池中最大的线程数 // keepAliveTime临时线程的存活时间 // unit,时间单位(时分秒) // workQueue, 任务队列 // threadFactory, 为线程池创建线程的线程工厂 // handler:指定线程池的拒绝策略 // 1.AbortPolicy--丢弃任务并抛出异常默认拒绝策略 // 2.CallerRunsPolicy--由主线程负责调用run方法绕过线程池 // 3.DiscardOldestPolicy--抛弃队列中等待最久的任务把当前的任务加入到队列 // 4.DiscardPolicy--丢弃任务不抛出异常不推荐ThreadPoolExecutor pool new ThreadPoolExecutor(3, 6, 60, TimeUnit.SECONDS, new ArrayBlockingQueueRunnable(3),new MyThreadFactory(), new ThreadPoolExecutor.DiscardPolicy());// MyRun run new MyRun();pool.execute(new MyRun(任务1));//提交第一个任务线程池会自动创建一个新的线程自动处理任务pool.execute(new MyRun(任务2));pool.execute(new MyRun(任务3));ThreadPoolExecutor pool1 new ThreadPoolExecutor(3, 6, 60, TimeUnit.SECONDS, new ArrayBlockingQueueRunnable(3),new MyThreadFactory(), new ThreadPoolExecutor.DiscardPolicy());// MyRun run new MyRun();pool1.execute(new MyRun(任务1));//提交第一个任务线程池会自动创建一个新的线程自动处理任务pool1.execute(new MyRun(任务2));pool1.execute(new MyRun(任务3));}}class MyThreadFactory implements ThreadFactory {private static final AtomicInteger poolNumber new AtomicInteger(1);private final ThreadGroup group;private final AtomicInteger threadNumber new AtomicInteger(1);private final String namePrefix;MyThreadFactory() {SecurityManager s System.getSecurityManager();group (s ! null) ? s.getThreadGroup() :Thread.currentThread().getThreadGroup();namePrefix 池子- poolNumber.getAndIncrement() -线程-;}public Thread newThread(Runnable r) {Thread t new Thread(group, r,namePrefix threadNumber.getAndIncrement(),0);if (t.isDaemon())t.setDaemon(false);if (t.getPriority() ! Thread.NORM_PRIORITY)t.setPriority(Thread.NORM_PRIORITY);return t;} } 6. 线程池的执行流程 1. 提交一个新线程任务线程池会在线程池中分配一个空闲线程用于执行线程任务 2. 如果线程池中不存在空闲线程则线程池会判断当前“存活的线程数”是否小于核心线程数corePoolSize。         ○如果小于核心线程数corePoolSize线程池会创建一个新线程核心线程去处理新线程任务         ○如果大于核心线程数corePoolSize线程池会检查工作队列                 ■如果工作队列未满则将该线程任务放入工作队列进行等待。线程池中如果出现空闲线程将从工作队列中按照FIFO的规则取出1个线程任务并分配执行                 ■如果工作队列已满则判断线程数是否达到最大线程数maximumPoolSize                         ●如果当前“存活线程数”没有达到最大线程数maximumPoolSize则创建一个新线程非核心线程执行新线程任务                 ●如果当前“存活线程数”已经达到最大线程数maximumPoolSize直接采用拒绝策略处理新线程任务综上所述执行顺序为核心线程、工作队列、非核心线程、拒绝策略。 7. 线程池的状态 线程池的状态分为RUNNING,SHUTDOWN,STOP,TIDYING,TERMINATED ○ RUNNING 运行状态线程池被一旦被创建就处于RUNNING状态并且线程池中的任务数为0。该状态的线程池会接收新任务并处理工作队列中的任务。 调用线程池的shutdown()方法可以切换到SHUTDOWN关闭状态 调用线程池的shutdownNow()方法可以切换到STOP停止状态 ○SHUTDOWN关闭状态该状态的线程池不会接收新任务但会处理工作队列中的任务 当工作队列为空时并且线程池中执行的任务也为空时线程池进入TIDYING状态 ○STOP停止状态该状态的线程不会接收新任务也不会处理阻塞队列中的任务而且会中断正在运行 的任务 线程池中执行的任务为空,进入TIDYING状态; ○TIDYING整理状态该状态表明所有的任务已经运行终止记录的任务数量为0 terminated()执行完毕进入TERMINATED状态 ○TERMINATED: 终止状态该状态表示线程池彻底关闭。
http://www.dnsts.com.cn/news/30875.html

相关文章:

  • 青岛网站建设服务公司开通微信公众号流程需要什么
  • 如何创建一个免费网站贵州网站推广公司
  • 简单的网站建立怎么做网站建设与管理自考重点
  • 许昌市建设信息网站做打鱼网站的代理
  • 网站做好了 怎么做解析成都哪里可以做网站
  • 做我女朋友的表白句的网站公众号排版设计
  • 地方旅游网站模板凡科建站官网
  • 网站建设的经费预算报告罗湖住房和建设局网站
  • 苏州做网站设计的公司设计论坛最好的网站
  • 可以做平面设计兼职的网站云南建设厅网站公示
  • 网站建设有什么作用商贸行业网站建设哪家
  • 网站建设与维护浙江省试题陕西做天然气公司网站
  • 微信端网站开发流程图今天最新新闻摘抄
  • 网站后台如何修改密码免费国外网站空间
  • .net网站做增删改网站开发团队简介如何写
  • 钢铁行业公司网站模板自建网站怎么做二级页跳转
  • 专业的网站开发公司电话建设网站女装名字大全
  • 推荐做微商海报的网站免费网站模板 下载
  • 贵阳网站建设外包网站开发工资高嘛
  • 深圳网站设计收费西安百度首页优化
  • 临沂建设局官方网站基于php网站建设论文
  • 长沙网站建设大全如何开一家外贸网店
  • 做网站的图片要多少像素嵌入式软件开发笔试题目
  • vs2008可以做网站个人证书查询官网
  • 上传wordpress网站有没有高质量的网站都懂的
  • 如何借助织梦制作一个简单的网站域名注册成功后怎么使用网站
  • 大型网站建设公司有哪些动漫网站建设的目标
  • 制作一个动态企业网站wordpress 数据库填写
  • 网站统计怎么做机械设备上哪个网站做外贸推广
  • 网站备案当面核验怎么查看网站有没有做竞价