线程高级应用-心得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();
			}
		}
	}

}


 

 

posted @ 2013-02-07 13:58  yangkai_keven  阅读(143)  评论(0编辑  收藏  举报