一.多线程实现方式二:

1.目标:

/* 多线程实现方式二:实现Runnable接口
1.定义一个线程任务类MyRunnable实现Runnable接口,重写run方法;
2.创建MyRunnable任务对象
3.把MyRunnable任务对象交给Thread处理
4.调用线程对象start()方法启动线程;

 */

2.代码展示:

public class RunnableDemo {
    public static void main(String[] args) {
        //2.创建MyRunnable任务对象
        Runnable target=new MyRunnable();
        //3.把MyRunnable任务对象交给Thread处理
        Thread t=new Thread(target);
        //4.调用线程对象start()方法启动线程
        t.start();
        for (int i = 0; i < 5; i++) {
            System.out.println("主线程执行调用: "+i);

        }

    }
}
//1.定义一个线程任务类MyRunnable实现Runnable接口,重写run方法;
class MyRunnable implements Runnable{

    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println("子线程执行调用:"+i);

        }

    }
}

3.优缺点:

优点:线程任务类只是实现接口,还可以继续继承和实现接口,扩展性强。
缺点:编程多一层对象包装,如果线程有执行结果是不可以直接返回的。

4.语法形式:匿名内部类

//线程的创建方式二: 匿名内部类,(语法形式)
public class RunnableDemoOther {
    public static void main(String[] args) {
        //2.创建一个任务对象
     Runnable target=new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 5; i++) {
                    System.out.println("子线程执行调用: "+i);

                }
            }
        };
        //3.把MyRunnable任务对象交给Thread处理
        Thread t=new Thread(r);
        //4.调用线程对象start()方法启动线程
        t.start();
        for (int i = 0; i < 5; i++) {
            System.out.println("主线程执行调用: "+i);

        }

    }
}

二.多线程实现方式三:

1.针对于前两种继承Thread类和实现Runnable接口,都存在共性问题?

1.两者重写Run方法都不能直接返回结果;
2不适合需要返回执行结果的业务场景;

2.怎么解决呢?

我们接下来开始学习多线程实现方式三: JDK 5.0 提供实现Callable和FutureTask接口来实现,解决可以直接返回结果的业务。

3.需求分析

/*多线程实现方案三:利用callable和futureTask接口实现
1,创建任务类,实现callable接口,重新call方法,封住要做的事情
2.用futureTask把callable对象封装成线程任务对象
3.把线程任务交给Thread处理
4.调用Thread的start方法启动线程,执行任务
5.执行完毕,通过futureTask的get方法获取任务执行的结果

 */

4.代码实现:

//1.定义一个任务类实现callable接口重写call方法 声明程序执行结果的类型String
class MyCallable implements Callable<String> {
    private int n;
    public MyCallable(int n) {
        this.n = n;
    }

    //2.线程的任务方法;计算1到100/200的和
    @Override
    public String call() throws Exception {
        int sum = 0;
        for (int i = 0; i <= n; i++) {
            sum += i;
        }
        System.out.println(Thread.currentThread().getName());
        return "子线程的执行结果是:" + sum;
    }
}
public class CallableDemo {
    public static void main(String[] args)  {
        //创建callable任务对象
        Callable<String> call = new MyCallable(100);
        //futureTask对象作用1:是Runnable的对象(实现Runnable接口),交给Thread
        //futureTask对象作用2: 可以在线程执行完毕之后通过调用get方法得到线程执行之后的结果:
        FutureTask<String> f1 = new FutureTask<>(call);
        //交给线程处理
        Thread t1 = new Thread(f1);
        //启动线程
        t1.start();

        Callable<String> call2 = new MyCallable(200);
        FutureTask<String> f2 = new FutureTask<>(call2);
        Thread t2 = new Thread(f2);
        t2.start();

        try {
            String s1 = f1.get();
            System.out.println("第一个结果:"+s1);
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            String s2 = f2.get();
            System.out.println("第二个结果:"+s2);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}

优缺点:

1.优点:线程任务类只是实现接口,可以继续继承类和实现接口,扩展性强;
可以在线程执行完毕之后get执行结果;
缺点:代码复杂一点;