滴水穿石-09多线程

1:多线程概述

  私以为多线程就是一个进程中同时又多个线程执行,就是“多线程”。从代码的角度理解就是一个程序中有多个方法同时运行。(可能不是很准确)

2:多线程实现方案

  创建新执行线程有两种方法。一种方法是将类声明为 Thread 的子类。该子类应重写 Thread 类的 run 方法。接下来可以分配并启动该子类的实例。

       创建线程的另一种方法是声明实现 Runnable 接口的类。该类然后实现 run 方法。然后可以分配该类的实例,在创建 Thread 时作为一个参数来传递并启动。

2.1 继承Thread 类  

1:创建MyThread继承Thread类
2:重写run()方法
3:创建对象
4:启动线程
步骤

 MyThread 1.0

package d9;

public class MyThreadDemo {
    public static void main(String[] args) {
        //创建线程对象
        MyThread my = new  MyThread();
        MyThread my2 = new  MyThread();
        //my.run();
        //my.run(); 
        //run() 方法仅仅是封装该线程执行的代码,直接调用是管道方法
        //start() 方法首先启动了线程,然后再由jvm去掉用该线程的run方法
        my.start();
        my2.start();
    }
}
MyThreadDemo 1.0

2.2 继承Runnable接口

1:自定义一个类MyRunnable实现Runnable接口
2:重写run()方法
3:创建MyRunnable类的对象
4:创建Threadle的对象,并把3创建的对象以参数形式传递
步骤
package d9;

public class MyRunnable implements Runnable {

    @Override
    public void run() {
        // TODO Auto-generated method stub
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }

}
Runnable
package d9;

public class MyRunnableDemo {
    public static void main(String[] args) {
         MyRunnable my = new MyRunnable();
         Thread t1 = new Thread(my);
         Thread t2 = new Thread(my,"李四");
         
         t1.setName("张三");
        
         t1.start();
         t2.start();
    }
}
MyRunnableDemo

 

2.3 Callable,会在线程池部分讲解

3:设置和获取线程名称

package d9;

public class MyThread extends Thread {
    public MyThread() {}
    public MyThread(String name) {
        super(name);
    }
    @Override
    public void run() {
        // TODO Auto-generated method stub
        for (int i = 0; i < 100; i++) {
            System.out.println(getName()+" : "+ i);
        }
    }
}
MyThread
package d9;

public class MyThreadDemo {
    public static void main(String[] args) {
        //创建线程对象
        MyThread my = new  MyThread("逍遥");
        MyThread my2 = new  MyThread();
        //my.run();
        //my.run(); 
        //run() 方法仅仅是封装该线程执行的代码,直接调用是管道方法
        //start() 方法首先启动了线程,然后再由jvm去掉用该线程的run方法
    
        my2.setName("小天狼");//给线程命名
        my.start();
        my2.start();
        
        //输出当前线程的方法名臣
        System.out.println(Thread.currentThread().getName());
    }
}
MyThreadDemo

 

4:线程调度和线程控制

 4.1线程调度

package d9;

public class ThreadPriority extends Thread {
@Override
public void run() {
    // TODO Auto-generated method stub
    for (int i = 0; i <100; i++) {
        System.out.println(getName()+": "+i);
    }
}
}
ThreadPriority
package d9;

public class ThreadPriorityDemo {

    public static void main(String[] args) {
        //创建线程对象
        MyThread my = new  MyThread("逍遥");
        MyThread my2 = new  MyThread();
         
        my2.setName("小天狼");//给线程命名
        my.start();
        my2.start();
        //线程优先级的范围1-10默认为5
        my2.setPriority(1);
         
    }

}
ThreadPriorityDemo

 4.2线程控制

  4.2.1 线程休眠

package d9;
import java.util.Date;

public class ThreadSleep extends Thread {
    @Override
    public void run() {
        // TODO Auto-generated method stub
         for (int i = 0; i < 10; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
            System.out.println(getName()+":"+i+"当前时间"+new Date());
        }
    }
}
ThreadSleep
package d9;

public class ThreadSleepDemo {
    
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        ThreadSleep s1 = new ThreadSleep();
        ThreadSleep s2 = new ThreadSleep();
        ThreadSleep s3 = new ThreadSleep();
        
        s1.setName("张三");
        s2.setName("李四");
        s3.setName("王五");
        
        s1.start();
        s2.start();
        s3.start();
    }
}
ThreadSleepDemo

 

  4.2.2 线程加入 

package d9;

public class ThreadJoin extends Thread {
    @Override
    public void run() {
        // TODO Auto-generated method stub
        for (int i = 0; i < 100; i++) {
            System.out.println(getName()+" : "+ i);
        }
    }
}
ThreadJoin
package d9;

public class ThreadJoinDemo {
    
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        ThreadJoin s1 = new ThreadJoin();
        ThreadJoin s2 = new ThreadJoin();
        ThreadJoin s3 = new ThreadJoin();
        
        s1.setName("张三");
        s2.setName("李四");
        s3.setName("王五");
        
        s1.start();
        try {
            s1.join();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        s2.start();
        s3.start();
    }
}
ThreadJoinDemo

  4.2.3 线程礼让(并不能完全实现)

 package d9;

public class ThreadYield extends Thread {
     
    @Override
    public void run() {
        // TODO Auto-generated method stub
        for (int i = 0; i < 100; i++) {
            System.out.println(getName()+" : "+ i);
            Thread.yield();
        }
    }
}
ThreadYield
package d9;

public class ThreadYieldDemo {
    public static void main(String[] args) {
        //创建线程对象
        ThreadYield my = new  ThreadYield();
        ThreadYield my2 = new  ThreadYield();
         
        my.setName("逍遥");;
        my2.setName("小天狼");//给线程命名
        my.start();
        my2.start();
         
    }
}
ThreadYieldDemo

 

  4.2.4 后台线程(守护线程)

package d9;

public class ThreadDaemon extends Thread {
     
    @Override
    public void run() {
        // TODO Auto-generated method stub
        for (int i = 0; i < 100; i++) {
            System.out.println(getName()+" : "+ i);             
        }
    }
}
ThreadDaemon
package d9;

public class ThreadDaemonDemo {
    public static void main(String[] args) {
        //创建线程对象
        ThreadDaemon my = new  ThreadDaemon();
        ThreadDaemon my2 = new  ThreadDaemon();
         
        my.setName("逍遥");;
        my2.setName("小天狼"); 
        my.setDaemon(true);
        my2.setDaemon(true);
        my.start();
        my2.start();
        
        Thread.currentThread().setName("杨小可");
        for(int x=0;x<5;x++) {
            System.out.println(Thread.currentThread().getName());
        }
    }
}
ThreadDaemonDemo

 

  4.2.5 中断线程

package d9;

public class ThreadInterruptDemo {
    public static void main(String[] args) {
        //创建线程对象
        ThreadInterrupt my = new  ThreadInterrupt();
          
        my.setName("逍遥");;
     
        my.start();
        //超过3秒如果不醒来,就停止
        try {
            Thread.sleep(3000);
            my.interrupt();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
ThreadInterruptDemo
package d9;

import java.util.Date;

public class ThreadInterrupt extends Thread {
     
    @Override
    public void run() {         
        System.out.println("开始执行: "+new Date());
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            System.out.println("线程被终止了 ");
        }
        System.out.println("结束执行: "+new Date());
    }
}
ThreadInterrupt

 5 线程的生命周期

  5.1 简单生命周期

新建:创建线程对象
就绪:有执行资格,没有执行权
运行:有执行资格,有执行权
        阻塞:由于一些操作让线程保护欲了该状态,没有执行资格,没有执行权
                而另一些操作却可以把它激活,激活后处于就绪状态
死亡:线程对象变成垃圾,等待被回收
线程状态

 5.2 

常见的几种情况

A:新建—就绪—运行—结束
B:新建—就绪—运行—就绪—运行--结束
C:新建—就绪—运行—其他阻塞--就绪—运行—结束
D:新建—就绪—运行—同步阻塞--就绪—运行—结束
E:新建—就绪—运行—等待阻塞--同步阻塞--就绪—运行--结束

6 练习题

  6.1 模拟电影票售票系统

  6.1.1 版本1.0

package d9;

public class SellTicket implements Runnable {

    //定义一个资源 100张票
    int ticketNumber = 100;
    
    @Override
    public void run() {
        // TODO Auto-generated method stub
        while (true) {
            if (ticketNumber>0) {
                System.out.println(Thread.currentThread().getName()+"正在出售第"+ticketNumber+"张票");
                ticketNumber--;
            }else {
                break;
            }
        }
    }

}
SellTicket
package d9;

public class SellTicketDemo {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        SellTicket st = new SellTicket();
        
        Thread t1 = new Thread(st,"窗口1");
        Thread t2 = new Thread(st,"窗口2");
        Thread t3 = new Thread(st,"窗口3");
        
        t1.start();
        t2.start();
        t3.start();
    }

}
SellTicketDemo

  6.1.2版本2.0 

  由1.0可以查看出有重复票卖出.这时候应该用static定义一个全局变量

6.1.3 同步代码块

 线程安全分析:由于该线程是多线程的,而且有共享资源(100张票).并且有多条语句操作共享数据(三个窗口).所以会存在安全隐患

同步代码块:
        synchronized(对象){
         需要同步的代码;
    }    
同步代码块

同步方法:即把同步关键字加在方法上,此时的锁对象是this

静态方法的锁对象是累的字节码文件,即SellTicket.class

6.1.4 锁

 6.1.5 死锁:两个锁资源由于相互调用而出现相互等待的现象

1 package d9;
2 
3 public class MyLock {
4     //第一步,创建两把锁对象
5     public static final Object objA = new Object();
6     public static final Object objB = new Object();
7 }
创建两把锁对象
 1 package d9;
 2 
 3 public class DieLock extends Thread {
 4     private boolean flag;
 5     public  DieLock (boolean flag) {
 6         this.flag = flag;                
 7     }
 8     public void run() {
 9          if (flag) {
10             synchronized (MyLock.objA) {
11                 System.out.println("if objA");
12                 synchronized(MyLock.objB) {
13                     System.out.println("if objB");
14                 }
15             }
16         }else {
17             synchronized (MyLock.objB) {
18                 System.out.println("else objB");
19                 synchronized(MyLock.objA) {
20                     System.out.println("else objA");
21                 }
22             }
23         }
24     }
25 }
DieLock
package d9;

public class DieLockDemo {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        DieLock di1 = new DieLock(true);
        DieLock di2 = new DieLock(false);
        
        di1.start();
        di2.start();
    }

}
DieLockDemo

 7 生产者消费者模式

1:资源类(Student)
2:生产者(SetThread)
3:消费者(GetThread)
4:测试类
思路

7.1 Version1.0

package StudentLX;

public class Student {
    //创建一个资源类,Student
    String name;
    int age;
}
Student
package StudentLX;

public class SetThread implements Runnable {
    private Student s;

    public SetThread(Student s) {
        this.s = s;
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub 
        s.name = "逍遥";
        s.age = 18;
    }

}
SetThread
package StudentLX;

public class GetThread implements Runnable {
    private Student s ;
     public GetThread (Student s) {
         this.s =s;                 
     }
    public void run() {
         
        System.out.println("姓名:"+s.name+"年龄: "+s.age);
    }
}
GetThread
package StudentLX;

public class StudentDemo {

    public static void main(String[] args) {
        //创建资源
        Student s = new Student();
        //设置和获取类
        GetThread gt= new GetThread(s);
        SetThread st= new SetThread(s);    
        //创建线程
        Thread t1 = new Thread(gt); 
        Thread t2 = new Thread(st);
        //启动线程
        t1.start();
        t2.start();
        
    }

}
StudentDemo

多线程问题是会存在安全隐患的.进一步修改SetThread和GetThread方法

7.2 Version2.0

package StudentLX;

public class SetThread implements Runnable {
    private Student s;

    public SetThread(Student s) {
        this.s = s;
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub 
        int i =1;
        while (true) {
            if (i%2==0) {
                s.name = "逍遥";
                s.age = 18;
            }else {
                s.name = "小天狼";
                s.age = 22;
            }
            i++;
        }
        
    }

}
SetThread
package StudentLX;

public class GetThread implements Runnable {
    private Student s ;
     public GetThread (Student s) {
         this.s =s;                 
     }
    public void run() {
         
         while (true) {
             System.out.println("姓名: "+s.name+";---: "+s.age);
             
        }
        
    }
}
GetThread

原因分析以及解决方法

A:多线程环境;B:共享同一资源;C共用同一代码.

解决方法线程同步:A:不同种类的线程都要加锁(GetThread和SetThread);B不同种类的线程加同一把锁

package StudentLX;

public class SetThread implements Runnable {
    private Student s;

    public SetThread(Student s) {
        this.s = s;
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        int i = 1;
        while (true) {
            synchronized (s) {
                if (i % 2 == 0) {
                    s.name = "逍遥";
                    s.age = 18;
                } else {
                    s.name = "小天狼";
                    s.age = 22;
                }
                i++;
            }
        }

    }

}
SetThread
package StudentLX;

public class GetThread implements Runnable {
    private Student s ;
     public GetThread (Student s) {
         this.s =s;                 
     }
    public void run() {
         
         while (true) {
             synchronized (s) {
                 System.out.println("姓名: "+s.name+";---: "+s.age);                 
            }             
        }        
    }
}
GetThread

 

  

7.3 Version3.0 等待唤醒机制

思路:

  A:生产者  先看是否有数据,有就等待;没有就生产,生产完之后通知消费者进行消费

  B:消费者  先看是否有数据,有就消费;没有就等待,通知生产者生产数据

等待唤醒

Object类中提供了三个方法

  wait():等待

  notify():唤醒单个线程

  notifyAll():唤醒所有线程

package StudentLX;

public class Student {
    //创建一个资源类,Student
    boolean flag;//定义一个标志,用于判断是否有数据
    String name;
    int age;
}
Student中定义一个标签
package StudentLX;

public class SetThread implements Runnable {
    private Student s;
    
    public SetThread(Student s) {
        this.s = s;
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        int i = 1;
        while (true) {
            synchronized (s) {
                //生产者:如果有就等待 ;如果没有就生产;
                if (s.flag) {
                    try {
                        s.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                if (i % 2 == 0) {
                    s.name = "逍遥";
                    s.age = 18;
                } else {
                    s.name = "小天狼";
                    s.age = 22;
                }
                i++;
                s.flag=true;
                //生产完成,通知消费者(唤醒线程)
                s.notify();
            }
        }

    }

}
SetThread进行改造
package StudentLX;

public class GetThread implements Runnable {
    private Student s ;
     public GetThread (Student s) {
         this.s =s;                 
     }
    public void run() {
         
         while (true) {
             synchronized (s) {
                 //消费者,如果有就消费;没有就等待
                 if (!s.flag) {
                    try {
                        s.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                 System.out.println("姓名: "+s.name+";---: "+s.age);        
                 //修改标记
                 s.flag=false;
                 s.notify();
            }             
        }        
    }
}
GetThread方法进行改造
package StudentLX;

public class StudentDemo {

    public static void main(String[] args) {
        //创建资源
        Student s = new Student();
        //设置和获取类
        GetThread gt= new GetThread(s);
        SetThread st= new SetThread(s);    
        //创建线程
        Thread t1 = new Thread(gt); 
        Thread t2 = new Thread(st);
        //启动线程
        t1.start();
        t2.start();
        
    }

}
测试类不变

 7.4  version4.0   Student变量私有化

package StudentLX;

public class Student {
    // 第一步,修改为私有成员
    private boolean flag;//  
    private String name;
    private int age;

    //第二步,创建SetStudent方法,并设置为同步方法
    public synchronized void  setStudent(String name,int age) {
        //如果存在,等待
         if (this.flag) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
         //创建
        this.name = name;
        this.age = age;
        //修改标签
        this.flag=true;
        //唤醒
        this.notify();
    }

    public synchronized void getStudent() {
        //如果不存在,等待
         if (!this.flag) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
         //使用
         System.out.println(this.name+"---"+this.age);
        //修改标签
        this.flag=false;
        //唤醒
        this.notify();
        
    }


     
     
}
Student
package StudentLX;

public class SetThread implements Runnable {
    private Student s;
    
    public SetThread(Student s) {
        this.s = s;
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        int i = 1;
        while (true) {
             
                if (i % 2 == 0) {
                    s.setStudent("逍遥", 18);
                } else {
                    s.setStudent("小天狼", 22);
                }
                i++;
                 
            }
        } 

}
SetThread
package StudentLX;

public class GetThread implements Runnable {
    private Student s ;
     public GetThread (Student s) {
         this.s =s;                 
     }
    public void run() {
         
         while (true) {
              s.getStudent();     
        }        
    }
}
GetThread
package StudentLX;

public class StudentDemo {

    public static void main(String[] args) {
        //创建资源
        Student s = new Student();
        //设置和获取类
        GetThread gt= new GetThread(s);
        SetThread st= new SetThread(s);    
        //创建线程
        Thread t1 = new Thread(gt); 
        Thread t2 = new Thread(st);
        //启动线程
        t1.start();
        t2.start();
        
    }

}
StudentDemo

8 线程组:多个线程组合到一起

package d9;

public class MyRunnable implements Runnable {

    @Override
    public void run() {
        // TODO Auto-generated method stub
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }

}
MyRunnable
package d9;

public class ThreadGroupDemo {

    public static void main(String[] args) {
        // 获取线程所属线程组的名称
        method1();
        // 设置线程所属的线程组
        method2();
    }

    private static void method2() {
        // 创建一个线程组
        ThreadGroup tg = new ThreadGroup("新的线程组");
        MyRunnable my = new MyRunnable();
        // 创建线程对象,并分组
        Thread t1 = new Thread(tg, my, "逍遥new");         
        Thread t2 = new Thread(tg, my, "小天狼new");
         
        // 输出线程名称
        System.out.println(t1.getThreadGroup().getName()  );
        System.out.println(t2.getThreadGroup().getName()  );
        // 通过线程组控制该组内的所有线程,例如:设置优先级和后台线程
        tg.setMaxPriority(4);
    }

    private static void method1() {
        MyRunnable my = new MyRunnable();
        Thread t1 = new Thread(my, "逍遥");
        Thread t2 = new Thread(my, "小天狼");

        // 获取线程的所属线程组
        ThreadGroup gt1 = t1.getThreadGroup();
        ThreadGroup gt2 = t2.getThreadGroup();

        // 通过ThreadGroup中的getName()方法获取线程组名称
        String name1 = gt1.getName();
        String name2 = gt2.getName();

        System.out.println(name1);
        System.out.println(name2);

        // 获取main线程的线程组名称
        System.out.println(Thread.currentThread().getThreadGroup().getName());
    }

}
ThreadGroupDemo

 9 线程池

9.1 通过实现Runnable接口

A:创建一个线程池对象,控制要创建几个线程对象
    public static ExecutorService newFixedThreadPoll(int nThreads) 
B:这种线程池的线程可以执行
    可以执行Runnable对象或者Callable对象代表的线程
    做一个类实现Runnable接口
C:调用如下方法
    Future<?> submit(Runnable task)
    <T> Future<T> subbmit(Callable<T> task)
步骤
package d9;

public class MyRunnable implements Runnable {

    @Override
    public void run() {
        // TODO Auto-generated method stub
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }

}
MyRunnable
package d9;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

class ExecutorsDemo {
    public static void main(String[] args) {
        // 创建线程池
        ExecutorService tpool = Executors.newFixedThreadPool(2);
        //创建线程对象,并放入到线程池中
        tpool.submit(new MyRunnable());
        tpool.submit(new MyRunnable());
        //结束线程池
        tpool.shutdown();
    }
}
ExecutorsDemo

 9.2 通过实现Callable接口

package d9;

import java.util.concurrent.Callable;

public class MyCallable implements Callable {

    @Override
    public Object call() throws Exception {
         for (int i = 0; i < 100; i++) {
             System.out.println(Thread.currentThread().getName()+":"+i);
        }
         
        return null;
    }

}
MyCallable
package d9;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CallableDemo {

    public static void main(String[] args) {
        //创建线程池对象
        ExecutorService pool = Executors.newFixedThreadPool(2);
        
        pool.submit(new MyCallable());
        pool.submit(new MyCallable());
    }
    }
CallableDemo

 9.3 通过实现Callable接口实现具有返回值的线程池(求和)

package d9;

import java.util.concurrent.Callable;

public class MyCallable implements Callable<Integer> {

    private int startNumber;
    private int endNumber;
    public MyCallable(int startNumber,int endNumber) {
        this.startNumber = startNumber;
        this.endNumber = endNumber;
    }
    @Override
    public Integer call() throws Exception {
         int sum=0;
         for (int i = startNumber; i <= endNumber; i++) {
             sum+=i;
        }
         
        return sum;
    }

}
MyCallable
package d9;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class CallableDemo {

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        //创建线程池对象
        ExecutorService pool = Executors.newFixedThreadPool(2);
        
    Future<Integer> sum1=    pool.submit(new MyCallable(1,100));
    Future<Integer> sum2=    pool.submit(new MyCallable(1,50));
    
    int f1 = sum1.get();
    
    System.out.println(f1);
    System.out.println(sum2.get());
    }
    }
CallableDemo

 10 匿名内部类实现多线程

package d9;

public class ThreadAnonymous {

    public static void main(String[] args) {
        // 01 继承Thread类 实现多继承
        new Thread() {
            public void run() {
                for (int i = 0; i < 100; i++) {
                    System.out.println("Hello" + i);
                }
            };
        }.start();
        // 02 通过实现runable接口来实现
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 100; i++) {
                    System.out.println("World" + i);
                }
            }
        }) {
        }.start();
        // 03 混合实现,其实只走方法内部的
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 100; i++) {
                    System.out.println("java" + i);
                }
            }
        }) {
            public void run() {
                for (int i = 0; i < 100; i++) {
                    System.out.println("!!" + i);
                }
            };
        }.start();
    }

}
ThreadAnonymous

 11 定时线程

   定时器:可以在指定的时间做某件事情,还可以重复做某件事情

  依赖Timer(定时)和TimerTask(任务)这两个类

import java.util.Timer;
import java.util.TimerTask;

public class TimeDemo {
    public static void main(String[] args) {
        //创建定时器对象
        Timer t = new Timer();
        //执行任务
        t.schedule(new MyTask(), 3000);
    }
}

class MyTask extends TimerTask{
    @Override
    public void run() {
        // TODO Auto-generated method stub
        System.out.println("beng,爆炸了!!!");
    }
}
version 1.0
import java.util.Timer;
import java.util.TimerTask;

public class TimeDemo {
    public static void main(String[] args) {
        //创建定时器对象
        Timer t = new Timer();
        //执行任务+结束任务
        t.schedule(new MyTask(t), 3000);
    }
}

class MyTask extends TimerTask{
    private Timer t;
    public MyTask() {}
    public MyTask(Timer t) {
        this.t =t;
    }
    @Override
    public void run() {
        // TODO Auto-generated method stub
        System.out.println("beng,爆炸了!!!");
        t.cancel();
    }
}
version 2.0 可以自动结束任务
 
import java.util.Timer;
import java.util.TimerTask;

public class TimeDemo {
    public static void main(String[] args) {
        //创建定时器对象
        Timer t = new Timer();
        //执行任务+结束任务
        //3秒后执行爆炸任务,如果不成功,每个2秒后再继续炸
        t.schedule(new MyTask(), 3000,2000);
    }
}

class MyTask extends TimerTask{
     
    @Override
    public void run() {
        // TODO Auto-generated method stub
        System.out.println("beng,爆炸了!!!");
         
    }
}
Version 3.0 连环炸

 练习:定时删除指定文件夹

package d9;

import java.io.File;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.Timer;
import java.util.TimerTask;

public class FolderDelete {
    public static void main(String[] args) throws ParseException {
        //创建定时器对象
        Timer t = new Timer();
        //执行任务 
        String stTime = "2018-3-30 07:21:06";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date d = sdf.parse(stTime);
        t.schedule(new DeleteFolder(), d,100000);
    }
}

class DeleteFolder extends TimerTask{
     
    @Override
    public void run() {
         File srcFolder = new File("D:\\aaa");
         deleteFolder(srcFolder);
        System.out.println("beng,爆炸了!!!");
         
    }

    private void deleteFolder(File srcFolder) {
        // TODO Auto-generated method stub
        File [] fileArray = srcFolder.listFiles();
        if (fileArray != null) {
            for (File file : fileArray) {
                if (file.isDirectory()) {
                    deleteFolder(file);
                }else {
                    file.delete();
                }
            }
            srcFolder.delete();
        }
    }
}
View Code

 

posted @ 2018-03-31 07:23  逍遥小天狼  阅读(209)  评论(0编辑  收藏  举报