通过实现Runnable接口的实现

package Thread;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class RunnableThreadDemo {

private static int POOL_NUM = 30; // 线程池数量

public static void main(String[] args) throws InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(10);
for (int i = 0; i < POOL_NUM; i++) {
RunnableThread thread = new RunnableThread();
//线程停顿
Thread.sleep(1000);
executorService.execute(thread);
}
// 关闭线程池
executorService.shutdown();
}

}

class RunnableThread implements Runnable {
@Override
public void run() {
System.out.println("通过线程池方式创建的线程Runnable方式:" + Thread.currentThread().getName() + " ");
}
}
通过实现Runnable接口的实现

package Thread;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;

public class CallableThreadDemo {

private static int POOL_NUM = 30; // 线程池数量

public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executorService = Executors.newFixedThreadPool(10);
for (int i = 0; i < POOL_NUM; i++) {
Callable<Integer> callableThread = new CallableThread();

FutureTask<Integer> thread = new FutureTask<Integer>(callableThread);
//线程停顿
Thread.sleep(1000);
//执行 Callable 方式,需要 FutureTask 实现类的支持,用于接收运算结果。 FutureTask 是 Future 接口的实现类
executorService.submit(thread);

System.out.println(thread.get());
}
// 关闭线程池
executorService.shutdown();
}
}

class CallableThread implements Callable<Integer> {

@Override
public Integer call() throws Exception {
System.out.println("通过线程池方式创建的线程Callable方式:" + Thread.currentThread().getName() + " ");
return 10086;
}
}

1.Callable规定的方法是call(),而Runnable规定的方法是run().
  2.Callable的任务执行后可返回值,而Runnable的任务是不能返回值的。  
  3.call() 方法可抛出异常,而run() 方法是不能抛出异常的。 
  4.运行Callable任务可拿到一个Future对象, Future表示异步计算的结果。 
  5.它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。 
  6.通过Future对象可了解任务执行情况,可取消任务的执行,还可获取任务执行的结果。
  7.Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其它线程执行的任务。

ExecutorService、Callable都是属于Executor框架。返回结果的线程是在JDK1.5中引入的新特征,还有Future接口也是属于这个框架,有了这种特征得到返回值就很方便了。 
通过分析可以知道,他同样也是实现了Callable接口,实现了Call方法,所以有返回值。这也就是正好符合了前面所说的两种分类

执行Callable任务后,可以获取一个Future的对象,在该对象上调用get就可以获取到Callable任务返回的Object了。get方法是阻塞的,即:线程无返回结果,get方法会一直等待。

再介绍Executors类:提供了一系列工厂方法用于创建线程池,返回的线程池都实现了ExecutorService接口。

public static ExecutorService newFixedThreadPool(int nThreads) 
创建固定数目线程的线程池。
public static ExecutorService newCachedThreadPool() 
创建一个可缓存的线程池,调用execute 将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。
public static ExecutorService newSingleThreadExecutor() 
创建一个单线程化的Executor。
public static ScheduledExecutorService newScheduledThreadPool(int 
corePoolSize) 
创建一个支持定时及周期性的任务执行的线程池,多数情况下可用来替代Timer类。
ExecutoreService提供了submit()方法,传递一个Callable,或Runnable,返回Future。如果Executor后台线程池还没有完成Callable的计算,这调用返回Future对象的get()方法,会阻塞直到计算完成。

为什么要用线程池:

1.减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。

2.可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因为消耗过多的内存,而把服务器累趴下(每个线程需要大约1MB内存,线程开的越多,消耗的内存也就越大,最后死机)。

Java里面线程池的顶级接口是Executor,但是严格意义上讲Executor并不是一个线程池,而只是一个执行线程的工具。真正的线程池接口是ExecutorService。

题外话,Thread表示一个线程,每个任务都创建一个线程肯定是不妥的,正确的做法应该是初始化一定量的Thread对象,实现Runnable接口创建表示任务的类,并把这些任务对给Thread线程执行。

我们应该是使用Runnable还是Thread?
Java不支持多继承,但允许实现多个接口。所以如果需要继承其他类,实现Runnable接口是好了。
---------------------
作者:性情中人1993
来源:CSDN
原文:https://blog.csdn.net/qq_38765404/article/details/81163959
版权声明:本文为博主原创文章,转载请附上博文链接!

Java多线程之Callable接口与Runnable的实现以及选择的更多相关文章

  1. Java多线程之Callable接口的实现

    Callable 和 Future接口  Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其它线程执行的任务. Callable和Runn ...

  2. java多线程之Callable、Future和FutureTask

    Java并发编程:Callable.Future和FutureTask 在前面的文章中我们讲述了创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable接口. 这2种方式都有一 ...

  3. Java多线程之Runnable与Thread

    Java多线程之Thread与Runnable 一.Thread VS Runnable 在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口:Thread类和 ...

  4. Java线程之Callable和Future

    本篇说明的是Callable和Future,它俩很有意思的,一个产生结果,一个拿到结果.        Callable接口类似于Runnable,从名字就可以看出来了,但是Runnable不会返回结 ...

  5. JAVA多线程之UncaughtExceptionHandler——处理非正常的线程中止

    JAVA多线程之UncaughtExceptionHandler——处理非正常的线程中止 背景 当单线程的程序发生一个未捕获的异常时我们可以采用try....catch进行异常的捕获,但是在多线程环境 ...

  6. java多线程之wait和notify协作,生产者和消费者

    这篇直接贴代码了 package cn.javaBase.study_thread1; class Source { public static int num = 0; //假设这是馒头的数量 } ...

  7. Java多线程之ConcurrentSkipListMap深入分析(转)

    Java多线程之ConcurrentSkipListMap深入分析   一.前言 concurrentHashMap与ConcurrentSkipListMap性能测试 在4线程1.6万数据的条件下, ...

  8. JAVA多线程之wait/notify

    本文主要学习JAVA多线程中的 wait()方法 与 notify()/notifyAll()方法的用法. ①wait() 与 notify/notifyAll 方法必须在同步代码块中使用 ②wait ...

  9. JAVA多线程之volatile 与 synchronized 的比较

    一,volatile关键字的可见性 要想理解volatile关键字,得先了解下JAVA的内存模型,Java内存模型的抽象示意图如下: 从图中可以看出: ①每个线程都有一个自己的本地内存空间--线程栈空 ...

随机推荐

  1. 添加用户到LDAP服务器

    1.  在浏览器中打开http://ldap.example.com/phpldapadmin 2. 点击[login]链接,输入管理员密码. 3. 点击[Create a new entry her ...

  2. Mysql介绍,与将脚本导入新数据库

    一:介绍 1.介绍 Mysql是最流行的关系型数据库管理系统,在WEB应用方面MySQL是最好的RDBMS(Relational Database Management System:关系数据库管理系 ...

  3. VIM中使用S查找并替换

    vi/vim 中可以使用 :s 命令来替换字符串.以前只会使用一种格式来全文替换,今天发现该命令有很多种写法(vi 真是强大啊,还有很多需要学习),记录几种在此,方便以后查询.:s/vivian/sk ...

  4. cookie之困

    参见http://yun.baidu.com/share/link?shareid=1575530779&uk=1795493794 cookie三元组(name,domain,path),它 ...

  5. js冲刺一下

    js中__proto__和prototype的区别和关系 1.对象有属性__proto__,指向该对象的构造函数的原型对象. 2.方法除了有属性__proto__,还有属性prototype,prot ...

  6. Javascript 严格模式use strict详解

    1.概述 除了正常运行模式,ECMAscript 5添加了第二种运行模式:"严格模式"(strict mode).顾名思义,这种模式使得Javascript在更严格的条件下运行. ...

  7. CSS选择符、属性继承、优先级算法以及CSS3新增伪类、新特性

    CSS 选择符有哪些?哪些属性可以继承?优先级算法如何计算? CSS3新增伪类有那些?CSS新增了哪些特性?下面我整理了一些,仅供参考. CSS 选择符: 1)      id选择器(# myid) ...

  8. 什么是 "use strict"? 使用它的好处和坏处分别是什么?

    ECMAscript 5添加了第二种运行模式:"严格模式"(strict mode).顾名思义,这种模式使得Javascript在更严格的条件下运行. 设立"严格模式&q ...

  9. 喵哈哈村的魔法考试 Round #6 (Div.3) 题解

    有任何问题 直接联系QQ:475517977 喵哈哈村的代码传说 第一章 冒泡排序 第一题就是排序嘛,在ACM/OI竞赛中,我只推崇一种排序方法,就是直接调用algorithm里面的sort函数. # ...

  10. POP3_关于 multipart/related;boundary=

    http协议对mime类型有详细描述,multipart/....是单个消息头包含多个消息体的解决方案.multipart媒体类型对发送非文本的各媒体类型是有用的.目前常用的有这些subtype: M ...