Java 实现多线程的三种方式

1、三种方法的介绍和比较

1、1三种方式得介绍

1、继承Thread类
2、实现Runnable接口
3、实现Callable接口

1、2三种方法的介绍和比较

1、2、1、实现Runnable接口相比继承Thread类有如下优势

1、增强程序的健壮性,将业务逻辑与线程调度分离
2、线程池只能放入实现Runable或Callable类线程,不能直接放入继承Thread的类

1、2、2、实现Runnable接口和实现Callable接口的区别

1、Runnable是自从java1.1就有了,而Callable是1.5之后才加上去的
2、实现Callable接口的任务线程能返回执行结果,而实现Runnable接口的任务线程不能返回结果
3、Callable接口的call()方法允许抛出异常,而Runnable接口的run()方法的异常只能在内部消化,不能继续上抛
4、加入线程池运行,Runnable使用ExecutorService的execute方法,Callable使用submit方法

2、如何创建线程

1、Thread

public class ThreadExtends {
    public static void main(String[] args) {
        new MyThread("线程1").start();
        new MyThread("线程2").start();
    }
}



class MyThread  extends  Thread{
    private String name;

    public MyThread(String name) {
        this.name = name;
    }

    @Override
    public void run() {

        System.out.println("线程:"+name);
    }

}

join() 线程合并,哪一个线程调用这个方法,其他线程就进入阻塞状态,直到调用线程执行完毕,其他线程进入就绪状态,继续等待争夺 CPU 资源
join(long millis) 哪一个线程调用这个方法,这个线程在一段时间内独占CPU资源,其他线程就进入阻塞状态,直到时间过去,其他线程进入就绪状态,继续等待争夺 CPU 资源
getState() 得到调用线程的状态
stop() 停止该线程 已废弃
suspend() 暂停该线程 已废弃
resume() 恢复线程 在suspend后使用 已废弃
interrupt() 请求终止该线程 设置线程状态为中断,配合Thread.currentThread().isInterrupted()使用,使用案例参考下面代码

2、Runnable

public class MyRunnable {
    public static void main(String[] args) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                int i=0;
                while (!Thread.currentThread().isInterrupted()){{
                  i++;
                    System.out.println(Thread.currentThread().getName()+" | 计数:"+i);
                  if (i==10){
                      Thread.currentThread().interrupt();
                  }
                }
                }
            }
        };
        new Thread(runnable,"线程1").start();

    }
}

3、Callable

public class MyCallable {
    public static void main(String[] args) {
        Callable<String> callable = new Callable<String>() {
            @Override
            public String call() throws Exception {
                return "线程1";
            }
        };
        FutureTask<String> task = new FutureTask<String>(callable);
        task.run();
        try {
        //获取Callable执行的结果 此方法会阻塞主线程直到获取返回结果
            System.out.println("返回值:"+task.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}