线程高级应用-心得1-传统线程和定时器讲解及案例分析
1.传统线程介绍
2.传统线程案例分析及知识点讲解
package com.itcast.family; /* * 传统线程的使用及注意事项 */ public class TraditionalThread { public static void main(String[] args) { //一、线程1;直接new一个thread子类,让子类run方法覆盖父类的run() Thread thread1 = new Thread(){ @Override public void run() { while(true){ try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } //线程1获取到的线程名字是从0开始的,即thread1--1:Thread-0 System.out.println("thread1--1:"+Thread.currentThread().getName()); //在这里this 即代表thread对象,因为直接new的是thread类 System.out.println("thread1--2:"+this.getName()); } } }; thread1.start(); /* * 运行结果: * thread1--1:Thread-0 thread1--2:Thread-0 */ //二、线程2;不new子类,给Thread类传一个Runnable参数的构造方法 Thread thread2 = new Thread(new Runnable(){ @Override public void run() { while(true){ try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("thread2--1:"+Thread.currentThread().getName()); /*这里就不能用this了,this在这里代表Runable对象,不是Thread线程对象了, * Runable是线程运行的代码宿主;所以要想获取该线程的名字一般都是用 * Thread.currentThread().getName();而不是this.getName() */ // System.out.println("thread2--2:"+this.getName()); } } }); thread2.start(); /* * 运行结果: * thread2--1:Thread-1 thread1--1:Thread-0 thread1--2:Thread-0 */ /* * 以上两种new 线程的方法有什么不同? * 第一种是new Thread线程对象,通过子类覆盖父类run()方法来达到需求; * 第二种是实现线程的构造方法,构造方法传入一个Runnable参数,实现其run(). * * 为什么大多数人都是使用第二种方法,而不是第一种? * 第二种方法更符合面向对象的思想 ;第二种方法把线程中运行的代码放到了一个Runnable对象中, * 固更加体现面向对象的思维;固使用第二种的方法比较普遍,更自然 */ //三、线程3;以下代码使用的是Thread中的run方法,而不是Runnable中的run方法 /* * 原因: * 如果不覆盖父类的run方法就以父类的run方法为主,如果覆盖了就以子类覆盖的run方法为主; * 父类的构造方法回去找Runnable中的run方法,所以这里的runnable不会执行 */ new Thread(new Runnable(){ @Override public void run() { while(true){ try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("thread3--Runnable:"+Thread.currentThread().getName()); } } }){ @Override public void run() { while(true){ try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("thread3--Thread:"+Thread.currentThread().getName()); } } }.start(); } /* * 单线程比多线程快,性能更低;因为多线程之间的切换也要费时间,cpu只有一个 * 比如: * 1、做馒头,我在一个桌子做馒头比在三个桌子做馒头快;看起来三个桌子都在产生馒头, * 但你在这三个桌子间来回走动也费时间; * 2、下载东西的时候为什么下载多个比下载一个快,这不是计算机本身加速了, * 而是服务器给你分了其他人的带宽,简单的说就是你抢了别人的网速; * 3、从u盘上把电脑上拷东西,考一个文件夹要不比分别考改文件下的子文件夹快。 */ } 3.定时器案例分析及知识点应用 package com.itcast.family; import java.util.Date; import java.util.Timer; import java.util.TimerTask; /* * 定时器Timer的使用 */ public class TraditionalTimer { //将其声明在此处是因为,内部类和方法内部不能声明静态变量 private static int count = 0; public static void main(String[] args) { /* * Timer:定时器schedule:调度Task:任务 */ /* * 1.一个简单的连环炸弹定时器,初步 new Timer().schedule(new TimerTask() { * * @Override public void run() { System.out.println("bombing!"); } }, * 6000, 3000); //用线程是为了显示休眠时间,隔1秒输出一个时间秒 while(true){ * System.out.println(new Date().getSeconds()); try { * Thread.sleep(1000); } catch (InterruptedException e) { * e.printStackTrace(); } } */ /* * 2.制造不同间隔交替执行的定时器,这是引出下面知识点的引子 * new Timer().schedule(new TimerTask() { @Override public void run() { System.out.println("bombing!"); new Timer().schedule( * new TimerTask() { * * @Override public void run() { * System.out.println("bombing!"); } } * * 内部再嵌套Timer的运行结果:33 34 35 36 37 38 * bombing! 39 40 bombing! 41 bombing! 42 43 * bombing! 44 this * 使用this代替再次Timer类放入运行结果: * 52 53 54 55 56 57 bombing! 58 * Exception in thread "Timer-0" * java.lang.IllegalStateException: * Task already scheduled or * cancelled * 分析:会出现定时器无法再调度的结果,因为这是匿名内部类 * 只能执行一次,不能循环执行 , 2000); } }, 6000, 3000); // 用线程是为了显示休眠时间,隔1秒输出一个时间秒 while (true) { System.out.println(new Date().getSeconds()); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } }*/ //3.优化交替执行定时器代码:比如:一个2分钟爆炸一回一个4分钟爆炸一回 class MyTimerTask extends TimerTask{ @Override public void run() { count = (count+1) % 2; System.out.println("bombing"); new Timer().schedule(new MyTimerTask(), 2000+2000*count); }} new Timer().schedule(new MyTimerTask(),2000); while (true) { System.out.println(new Date().getSeconds()); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }