Java多线程2

71 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第33天,点击查看活动详情

2.3、实现多线程方式三:实现Callable接口【应用】

  • 方法介绍

    方法名说明
    V call()计算结果,如果无法计算结果,则抛出一个异常
    FutureTask(Callable callable)创建一个 FutureTask,一旦运行就执行给定的 Callable
    V get()如有必要,等待计算完成,然后获取其结果
  • 实现步骤

    • 定义一个类MyCallable实现Callable接口
    • 在MyCallable类中重写call()方法
    • 创建MyCallable类的对象
    • 创建Future的实现类FutureTask对象,把MyCallable对象作为构造方法的参数
    • 创建Thread类的对象,把FutureTask对象作为构造方法的参数
    • 启动线程
    • 再调用get方法,就可以获取线程结束之后的结果。
  • 代码演示

    /*
     Future接口
    可以对具体Runnable、Callable任务的执行结果进行取消、查询是否完成、获取结果等。
    FutrueTask是Futrue接口的唯一的实现类
    FutureTask同时实现了Runnable, Future接口。它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值
    */
    
    public class MyCallable implements Callable<String> {
        @Override
        public String call() throws Exception {
            for (int i = 0; i < 100; i++) {
                System.out.println("跟女孩表白" + i);
            }
            // 返回值就表示线程运行完毕之后的结果
            return "答应";
        }
    }
    public class Demo {
        public static void main(String[] args) throws ExecutionException, InterruptedException {
            // 线程开启之后需要执行里面的call方法
            MyCallable mc = new MyCallable();
    
            // Thread t1 = new Thread(mc);
    
            // 可以获取线程执行完毕之后的结果.也可以作为参数传递给Thread对象
            FutureTask<String> ft = new FutureTask<>(mc);
    
            // 创建线程对象
            Thread t1 = new Thread(ft);
    
            String s = ft.get();
            // 开启线程
            t1.start();
    
            // String s = ft.get();
            System.out.println(s);
        }
    }
    
  • 三种实现方式的对比

    • 实现Runnable、Callable接口
      • 好处: 扩展性强,实现该接口的同时还可以继承其他的类
      • 缺点: 编程相对复杂,不能直接使用Thread类中的方法
    • 继承Thread类
      • 好处: 编程比较简单,可以直接使用Thread类中的方法
      • 缺点: 可以扩展性较差,不能再继承其他的类

2.4、设置和获取线程名称【应用】

  • 方法介绍

    方法名说明
    void setName(String name)将此线程的名称更改为等于参数name
    String getName()返回此线程的名称
    Thread currentThread()返回对当前正在执行的线程对象的引用
  • 代码演示

    public class MyThread extends Thread {
        public MyThread() {}
        public MyThread(String name) {
            super(name);
        }
    
        @Override
        public void run() {
            for (int i = 0; i < 100; i++) {
                System.out.println(getName()+":"+i);
            }
        }
    }
    public class MyThreadDemo {
        public static void main(String[] args) {
            MyThread my1 = new MyThread();
            MyThread my2 = new MyThread();
    
            //void setName(String name):将此线程的名称更改为等于参数 name
            my1.setName("高铁");
            my2.setName("飞机");
    
            //Thread(String name)
            MyThread my1 = new MyThread("高铁");
            MyThread my2 = new MyThread("飞机");
    
            my1.start();
            my2.start();
    
            //static Thread currentThread() 返回对当前正在执行的线程对象的引用
            System.out.println(Thread.currentThread().getName());
        }
    }
    

2.5、线程休眠【应用】

  • 相关方法

    方法名说明
    static void sleep(long millis)使当前正在执行的线程停留(暂停执行)指定的毫秒数
  • 代码演示

    public class MyRunnable implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 100; i++) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
    
                System.out.println(Thread.currentThread().getName() + "---" + i);
            }
        }
    }
    public class Demo {
        public static void main(String[] args) throws InterruptedException {
            /*
            System.out.println("睡觉前");
            Thread.sleep(3000);
            System.out.println("睡醒了");*/
    
            MyRunnable mr = new MyRunnable();
    
            Thread t1 = new Thread(mr);
            Thread t2 = new Thread(mr);
    
            t1.start();
            t2.start();
        }
    }