关于java:线程之ThreadRunnableCallable

5次阅读

共计 2008 个字符,预计需要花费 6 分钟才能阅读完成。

通常创立线程应用两种形式
1. 继承 Thread 类, 重写 run 办法

public class ThreadDemo extends Thread {

    @Override
    public void run() {System.out.println("创立线程形式 1");
    }

    public static void main(String[] args) {ThreadDemo threadDemo = new ThreadDemo();
        threadDemo.start();}
    
}

2. 实现 Runnable 接口(Runnbale 中只有一个 run 办法), 重写 run 办法。而后把实例作为参数传入 Thread 的构造方法中

public class ThreadDemo implements Runnable {

    @Override
    public void run() {System.out.println("创立线程形式 2");
    }

    public static void main(String[] args) {ThreadDemo threadDemo = new ThreadDemo();
        // 剖析源码
        new Thread(threadDemo).start();}

}

3. 剖析案例 2 中的源码得悉
1.Thread 实现了 Runnable 接口, 重写了 run 办法
2.threadDemo 在构造函数中作为参数传递给 Thread 中的 target 属性
3. 当执行线程的 run 办法时,target(threadDemo) 执行子类重写的 run 办法, 实现业务逻辑

public Thread(Runnable target) {init(null, target, "Thread-" + nextThreadNum(), 0);
}
// 只展现局部代码
private void init(ThreadGroup g, Runnable target, String name,
                  long stackSize, AccessControlContext acc,
                  boolean inheritThreadLocals) {if (name == null) {throw new NullPointerException("name cannot be null");
    }
    this.name = name;    
    SecurityManager security = System.getSecurityManager();
    this.group = g;  
    this.priority = parent.getPriority();  
    **this.target = target; ** 
}

@Override
public void run() {if (target != null) {target.run();
    }
}

无论哪种形式创立线程, 实质都是实现了 Runnable 接口, 重写了 run 办法。间接调用 run 办法不属于多线程

Java 线程的创立调用过程如上图所示。首先,Java 线程的 start 办法会创立一个本地线程(通过调用 JVM_StartThread),该线程的线程函数是定义在 jvm.cpp 中的 thread_entry,由其再进一步调用 run 办法。能够看到 Java 线程的 run 办法和一般办法其实没有本质区别,间接调用 run 办法不会报错,然而却是在以后线程执行,而不会创立一个新的线程。

4.FutureTask,Callable,FutureTask 也能够创立线程, 并且能够取得返回值

FutureTask 实现了 Runnable 接口重写 run 办法,同时能够作为参数传入 Thread 的构造函数。实现了 Future 接口, 能够通过 get(),cancel()获取返回值, 勾销线程。

public class FutureTaskDemo implements Callable<String> {
    
    @Override
    public String call() throws Exception {System.out.println("重写 Callable 中的 call 办法");
        return "success";
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException, TimeoutException {FutureTask task = new FutureTask(new FutureTaskDemo());        
        new Thread(task).start();
        // 获取返回值
        System.out.println(task.get());
    }
    
}

通过上面对 Thread 的剖析大抵, 在 Thread 中调用 FutureTask 的实例的 run 办法, 而后 run()中调用了 Callable 实例的 call 办法, 执行业务逻辑。同时获取返回值。

援用文章:https://segmentfault.com/a/11…

正文完
 0