Java创建线程有两种方法,一种是继承Thread,另一种实现Runnable或Callable接口。

一,继承Thread

public class APP {

    public static void main(String[] args) {
Thread thread = new Thread() {
@Override
public void run() {
int i = 0;
while (i < 100) {
System.out.println(i++);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
thread.start();
}
}

上述例子通过重写Thread的run方法,来定时输出i的值,但是要主要Thread的run方法仅仅是个普通的方法,必须要通过调用start方法才能创建线程去执行run方法,直接调用run就没有线程的创建了。

二,实现Runnable或Callable接口来创建线程。

这两个接口的实现只能是变成一个普通的类,要创建线程都必须要通过其他相关类开启的。

这两个接口最大的区别:Callable有返回值且能抛出受检测异常,而Runnable没有返回值也无法抛出受检测异常;

1,对于Runnable接口来说,

  要通过它来创建线程的的方法有两种,一种是通过Thread,另一种是通过Executor

public class APP {

    public static void main(String[] args) {

        class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("start -> "
+ Thread.currentThread().getName());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("end -> " + Thread.currentThread().getName());
} } Thread thread = new Thread(new MyRunnable());
thread.start(); Executor executor = Executors.newSingleThreadExecutor();
executor.execute(new MyRunnable());
}
}

2,对于Callable接口来说,

  要通过它来创建线程的的方法有两种,一种是通过Thread,另一种是通过ExecutorService,但是都要同时借助于Future接口来实现对Callable返回值的相关控制。这里的ExecutorService接口是继承了Executor接口的,它增加了一些功能,大家可以点开源码看看就知道,而实例化都是通过Executors类的静态方法来实现的。

2.1 通过Thread去创建

  由于Thread只能接受Runnable所以要想通过Thread去创建Callable线程,还要再借助一个即继承了Callable接口也继承了Runnable接口的类,这个类就是FutureTask。

2.2 通过ExecutorService去创建

  由于ExecutorService天然支持Callable接口,所以直接submit就可以了。

public class APP {

    public static void main(String[] args) throws Exception {

        class MyCallable implements Callable<Integer> {
@Override
public Integer call() throws Exception {
Thread.sleep(3000);
System.out.println("end");
return 200;
}
} ExecutorService es = Executors.newCachedThreadPool();
Future<Integer> future = es.submit(new MyCallable());
System.out.println("when ExecutorService -> " + future.get()); FutureTask<Integer> task = new FutureTask<Integer>(new MyCallable());
Thread thread = new Thread(task);
thread.start();
System.out.println("when Thread ->" + task.get());
}
}

备注:

Future的get方法是线程阻塞的,直到Callable的call()方法返回值为止。

再次提醒创建线程不要直接调用run方法。

如果发现理解不了,最好点进去看看源码。

最新文章

  1. C++整数转字符串的一种方法
  2. 基于DevExpress实现对PDF、Word、Excel文档的预览及操作处理
  3. java中的final的使用
  4. ArcGIS API for JavaScript 4.0(一)
  5. C# BackgroundWorker的使用 转
  6. springMvc源码学习之:spirngMvc获取请求参数的方法
  7. hdu 3397 Sequence operation(很有意思的线段树题)
  8. Spring+AOP+Log4j 用注解的方式记录指定某个方法的日志
  9. Square(强大的剪枝)
  10. devexpress实现单元格合并以及依据条件合并单元格
  11. 04(1) 基于上下文相关的GMM-HMM声学模型1
  12. c#使用js上传图片
  13. CentOS下配置SS5(SOCKS5)代理服务器
  14. 利用蒙特卡洛(Monte Carlo)方法计算π值[ 转载]
  15. CentOS中配置Kafka集群
  16. [Android P] Android P版本 新功能介绍和兼容性处理(一)
  17. EF + MySql 错误:配置错误 无法识别的元素“providers”
  18. 多线程(JDK1.5的新特性互斥锁)
  19. Asp.NetCore取配置信息
  20. js教程系列32 :javascript-DOM节点操作

热门文章

  1. iconfont阿里妈妈前端小图标使用方法详解
  2. 转】从源代码剖析Mahout推荐引擎
  3. 转】Spark DataFrame小试牛刀
  4. 【126】win8的一些问题
  5. 用 const 限定类的成员函数
  6. 无责任Windows Azure SDK .NET开发入门篇一[Windows Azure开发前准备工作]
  7. Mes首检确认统计的存储过程
  8. 关于Collection&#39;
  9. Yeoman+Express+Angular在Linux上开发配置方法
  10. ecmall二次开发 直接实例化mysql对象