zoukankan      html  css  js  c++  java
  • 滴水穿石-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
  • 相关阅读:
    1-素材库同步:将素材组的素材同步到oss
    MongoDB_2:mongodb高级聚合查询
    关于python:如果键存在,则删除字典项
    Kafka学习-分布式日志系统 / 消息队列
    摘要算法—md5简介
    mac使用pyenv安装和管理多个python版本
    如何mac电脑上查看安装了几个python?
    mac os-Homebrew的安装及使用
    第一次博客
    个人介绍
  • 原文地址:https://www.cnblogs.com/YK2012/p/8504052.html
Copyright © 2011-2022 走看看