黑马程序员技术交流社区

标题: 多线程部分案例总结2 [打印本页]

作者: xiaolongwang    时间: 2015-12-7 13:10
标题: 多线程部分案例总结2
12.线程间通信问题
        A:等待唤醒(使用Object类中提供的三个方法)
                wait():等待
                notify():唤醒单个线程
                notifyAll():唤醒所有线程
        注意:以上三个方法需要通过锁对象调用,而锁对象可以是任意对象,所以这三个方法必须定义在Object类中       
       
        B:以生产者和消费者多线程体现
                资源类:Student
                设置数据类:SetThread        (生产者)
                获取数据类:GetThread        (消费者)
                测试类:StudentDemo
       
        public class Student {
                String name;
                int age;
                boolean flag;
        }
       
        public class SetThread implements Runnable{
                private Student s;
                private int x = 0;
                public SetThread(Student s){
                        this.s = s;
                }
               
                public void run(){
                        while(true){
                                synchronized(s){
                                        if(s.flag){
                                                try{
                                                        s.wait();
                                                }catch(InterruptedException e){
                                                        e.printStackTrace();
                                                }
                                        }
                                        if(x%2 == 0){
                                                s.name = "高渐离";
                                                s.age = 30;
                                        }else{
                                                s.name = "雪女";
                                                s.age = 28;
                                        }
                                        x++;
                                        s.flag = true;
                                        s.notify();
                                }
                        }
                }
        }
       
        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){
                                                        e.printStackTrace()
                                                }
                                        }
                                        System.out.println(s.name + " --- " + s.age);
                                        s.flag = false;
                                        s.notify();
                                }
                        }
                }
        }
       
        public class StudentDemo {
                public static void main(String[] args){
                        //创建资源对象
                        Sudent s = new Student();
                        //创建设置和获取对象
                        SetThread st = new SetThread(s);
                        GetThread gt = new GetThread(s);
                        //创建设置和获取线程
                        Thread t1 = new Thread(st);
                        Thread t2 = new Thread(gt);
                        //启动线程
                        t1.start();
                        t2.start();
                }
        }       
       
13.线程组
        A:常用功能
                ThreadGroup(String name):通过该构造方法创建线程组
                Thread(ThreadGroup group,Runnable target,String name):将线程添加到线程组,并为线程组命名
                public final ThreadGroup getThreadGroup():获取该线程所属线程组
                public final String getName():返回该线程组名称
                Thread.currentThread().getThreadGroup().getName():获取正在运行的线程所属线程组的名称
       
        B:代码演示
        public class MyRunnable implements Runnable{
                public void run(){
                        for(int x = 0; x < 100; x++){
                                System.out.println(Thread.currentThread().getName() +  ":" + x);
                        }
                }
        }
       
        public class ThreadGroupDemo{
                public static void main(String[] args){
                        MyRunnable mr = new MyRunnable();
                        ThreadGroup tg = new ThreadGroup("线程组一");
                       
                        Thread t1 = new Thread(tg,mr,"线程A");
                        Thread t2 = new Thread(tg,mr,"线程B");
                       
                        System.out.println(t1.getThreadGroup().getName());
                        System.out.println(t2.getThreadGroup().getName());
                        //通过线程组名称设置改组线程为后台线程
                        tg.setDaemon(true);
                       
                        t1.start();
                        t2.start();
                }
        }
       
14.线程池
        线程池的好处:
                线程池里的每一个线程代码结束后,并不会死亡,而是再次回到线程池中成为空闲状态,等待先一个对象来使用
               
        A:常用方法
                创建线程池
                public static ExecutorService newFixedThreadPool(int nThreads)
                调用方法
                Future<?> submit(Runnable task):执行Runnable对象
                <T> Future<T> submit(Callable<T> task):执行Collable对象
                结束线程池
                void shutdown();
        注意:Future<V> :表示计算结果,使用 V get() 方法获取结果
                  Collable 重写的是 call() 方法,该方法有返回值,返回值类型为Callable<T>泛型类型
                  若没有指定泛型类型,则默认使用Object类型
                  
        B:多线程的线程池实现方式
                a:实现Runnable接口
        public class MyRunnable implements Runnable {
                public void run(){
                        for(int x = 0;x < 100;x++){
                                System.out.println(Thread.currentThread().getName() + ":" + x);
                        }
                }
        }
       
        public class ExecutorsDemo{
                public static void main(String[] args){
                        //创建线程池,设置要创建的线程对象的数量
                        ExecutorService pool = Executors.newFixedThreadPool(2);
                        //执行Runnable对象代表的线程
                        pool.submit(new MyRunnable());
                        pool.submit(new MyRunnable());
                        //结束线程
                        pool.shutdown();
                }
        }
       
                b:实现Callable<T>接口(多线程求和案例)
        public class MyCollable implements Callable<Integer> {
                private int number;
                public MyCollable(int number){
                        this.number = number;
                }
               
                public Integer call() throws Exception {
                        int sum = 0;
                        for(int x = 1; x <= number; x++){
                        sum += x;
                        }
                        return sum;
                }
        }       
               
        public class CallableDemo{
                public static void main(String[] args) throws InterruptedException, ExecutionException{
                        //创建线程池对象,设置数量
                        ExecutorService pool = Executors.newFixedThreadPool(2);
                        //执行Collable<T>对象代表的线程
                        Future<Integer> f1 = pool.submit(new MyCollable(100));
                        Future<Integer> f2 = pool.submit(new MyCollable(200));
                        //使用V get() 方法获取计算结果
                        Integer i1 = f1.get();
                        Integer i2 = f2.get();
                        //结束线程池
                        pool.shutdown();
                }
        }
       
15.多线程的匿名内部类实现方式
        public class ThreadDemo{
                public static void main(String[] args){
                        //基础Thread类实现多线程(使用子类对象)
                        new Thread(){
                                public void run(){
                                        for(int x = 0; x < 100; x++){
                                                System.our.println(Tread.currentThread().getName() + ":" +x)
                                        }
                                }
                        }.start();
                       
                        //实现Runnable接口来实现多线程(使用匿名内部类)
                        new Thred(new Runnable(){
                                public void run(){
                                        for(int x = 0; x < 100; x++){
                                                System.out.println(Thread.currentThread().getName() + ":" +x);
                                        }
                                }
                       
                        }){}.start();
               
                }
        }
        注意:若同时子类对象和匿名内部类都为线程,不会报错,但只执行子类对象线程
       
16.        定时器
        定时器:可以实现在指定的时间内做某件事,还可以实现重复的做某件事
        定时器依赖Timer和TimerTask这两个类
        Timer:定时
        TimerTask:任务
       
        A:常用功能
                punlic Timer():创建定时器对象的构造方法
                public void schedule(TimerTask task,long dalay):指定多长时间后执行任务
                public void schedule(TimerTask task,long delay,long period):指定多长时间后执行任务,指定多长时间后再次执行任务
                public void cancel():取消计时器任务
       
        B:案例演示
        public class TimerDemo{
                public static void main(String[] args){
                        //创建定时器对象
                        Timer t = new Timer();
                        //执行任务
                        t.schedule(new MyTask(),3000,2000);
                        //结束任务
                        t.cancel()
                }
        }
       
        public class MyTask extends TimerTask{
                public void run(){
                        System.out.println("任务已执行!");
                }
        }
       
        C:在指定的时间内删除指定的目录
        public class TimerTest{
                public static void main(String[] args) throws ParseException {
                        Timer t = new Timer();
                       
                        String str = "2015-12-12 23:59:59";
                        SimpleDeteFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        Date d = sdf.parse(s);
                       
                        t.schedule(new DeleteFolder(),d);
                }
        }
       
        public class DeleteFolder extends TimerTask{
                public void run(){
                        File srcFolder = new File("demo");
                        deleteFolder(srcForder);
                }
                //递归删除目录
                public void deleteFolder(File srcFolder){
                        File[] fileArray = srcFolder.listFiles();
                        if(fileArray != null){
                                for(File file : fileArray){
                                        if(file.isDirectory()){
                                                deleteFolder(file);
                                        }else{
                                                System.out.println(file.getName()+ ":" +file.delete());
                                        }
                                }
                                System.out.println(srcFolder.getName()+ ":" +srcFolder.delete());
                        }
                }
        }




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2