1.1java实现多线程的方式Thread,Runnable,Callable

java实现多线程

编写多线程程序是为了实现多任务的并发执行,从而能够更好地与用户交互。
一般有三种方法,Thread,Runnable,Callable.

实现Runnable接口相比继承Thread类有如下优势:
1.可以避免由于Java的单继承特性而带来的局限;
2.增强程序的健壮性,代码能够被多个线程共享,代码与数据是独立的;
3.适合多个相同程序代码的线程区处理同一资源的情况。

实现Runnable接口和实现Callable接口的区别:
1.Runnable是自从java1.1就有了,而Callable是1.5之后才加上去的
2.Callable规定的方法是call(),Runnable规定的方法是run()
3.Callable的任务执行后可返回值,而Runnable的任务是不能返回值(是void)
4.call方法可以抛出异常,run方法不可以
运行Callable任务可以拿到一个Future对象,表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。通过Future对象可以了解任务执行情况,可取消任务的执行,还可获取执行结果。
加入线程池运行,Runnable使用ExecutorService的execute方法,Callable使用submit方法。

1.继承Thread

public class ThreadByExtends {

         public static void main(String[] args) {
               // TODO Auto-generated method stub
                new MyThread().start();
             }

     }

     class MyThread extends Thread {
         private int ticket = 1;

         public void run() {

                 for (int i = 0; i < 10; i++) {
                         if (ticket > 0) {
                                 System.out.println("车票第" + ticket-- + "张");
                             }
                     }
             }

     }

2.实现接口runnable

 public class ThreadRunnable {

            public static void main(String[] args) {
                   MyThread1 myThread = new MyThread1();
                    new Thread(myThread).start();
                }
}

        class MyThread1 implements Runnable {

           private int ticket = 1;

            public void run() {
                    for (int i = 0; i < 10; i++) {
                            if (ticket > 0) {
                                    System.out.println("ticket = " + ticket--);
                                }
                        }
                }

        }

3.实现Callable接口

运行Callable任务可以拿到一个Future对象,Future 表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并获取计算的结果。计算完成后只能使用 get 方法来获取结果,
  如果线程没有执行完,Future.get()方法可能会阻塞当前线程的执行;
  如果线程出现异常,Future.get()会throws InterruptedException或者ExecutionException;
  如果线程已经取消,会跑出CancellationException。
取消由cancel 方法来执行。isDone确定任务是正常完成还是被取消了。一旦计算完成,就不能再取消计算。如果为了可取消性而使用 Future 但又不提供可用的结果,则可以声明Future

public interface Future<V> {
    boolean cancel(boolean mayInterruptIfRunning);
    boolean isCancelled();
    boolean isDone();
    V get() throws InterruptedException, ExecutionException;
    V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;

    public class ThreadCallable  {

        public static void main(String[] args) {

            MyThread2 myThread2 = new MyThread2();

            FutureTask<Integer> futureTask = new FutureTask<>(myThread2);
            new Thread(futureTask, "线程名:有返回值的线程2").start();

            try {
                System.out.println("子线程的返回值:" + futureTask.get());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    class MyThread2 implements Callable<Integer> {

        public Integer call() throws Exception {
            System.out.println("当前线程名——" + Thread.currentThread().getName());
            int i = 0;
            for (; i < 5; i++) {
                System.out.println("循环变量i的值:" + i);
            }

            return i;
        }

    }

猜你喜欢

转载自blog.csdn.net/c_royi/article/details/81092818