面试求职中需要了解的Java多线程知识
Java中多线程的实现方式
在java的历史版本中,有两种创建多线程程序的方法
1) 通过创建Thread类的子类来实现(Thread类提供了主线程调用其它线程并行运行的机制)
主要步骤:
自定义类继承Thread类,然后覆盖其中的run方法,使得该线程能够完成特定的工作,使用start方法启动线程,将执行权转交到run.
2) 通过实现Runable接口的类来实现(推荐,可以实现数据共享,而且可以避免因为类单继承的局限)
主要步骤:
a>. 创建某个类实现Runnable接口,实现run()方法。
b>. 创建Thread对象,用实现Runnable接口的对象作为参数实例化该Thread对象。
c>. 调用Thread的start方法。
说明:
Thread是一个类,而Runnable是一个接口.
JAVA线程控制着程序执行的主路径;当你用java命令调用JVM时,JVM创建了一个隐式线程来执行main方法.
3) 在JDK5.0后,使用Executor框架管理线程.
虽然可以使用Thread类来显示的创建线程,但推荐的做法是使用Executor接口,让它来管理Runnable对象的执行.
通常Executor对象会创建并管理一组执行Runnable对象的线程,这组线程被称为线程池,Executor基于生产者-消费者模式.提交任务的执行者是生产者(产生待完成的工作单元),执行任务的线程是消费者(消耗掉这些工作单元)
采用Executor的优势
a) Executor对象能够复用已有的线程,从而消除了为每个任务创建新线程的开销,
b) 它能通过优化线程的数量,提高程序性能,保证处理器一直处于忙碌状,而不必创建过多的线程使程序资源耗尽。
Executor接口的定义[JDK源码引入]
public interface Executor{
void execute(Runnable command);
}
ExecutorService接口[JDK源码引入]
public interface ExecutorService extends Executor {
void shutdown();
List<Runnable> shutdownNow();
boolean isShutdown();
boolean isTerminated();
boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException;
<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);
Future<?> submit(Runnable task);
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
throws InterruptedException;
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException;
<T> T invokeAny(Collection<? extends Callable<T>> tasks)
throws InterruptedException, ExecutionException; <T> T invokeAny(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
ExecutorService暗示了生命周期的3种状态:运行(running)、关闭(shutting down)和终止(terminated).
ExecutorService最初创建后的初始状态是运行状态.shutdown方法会启动一个平缓的关闭过程:停止接受新的任务,同时等待已经提交的任务完成-包括尚未开始执行的任务. shutdownNow方法会启动一个强制关闭过程,尝试取消所有运行中的任务和排在队列中尚未开始的任务.在关闭后提交到ExecutorService的任务会抛出RejectedExecution异常.
Executors类,该类是一个独立类,提供一系列灵活的线程池实现和一些有用的预设配置.[JDK源码引入]
public class Executors {
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
... ...
}
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类。
新线程实例应用
使用新线程实现一个无返回的线程实例
public class ThreadPoolTest { public static void main(String[] args) {
//使用动态缓存线程池,池中的线程随着任务数量的变化而变化
ExecutorService threadPool = Executors.newCachedThreadPool();
//循环产生5个任务丢给线程池
for(int i=1; i<=5; i++){
final int taskNum = i;
threadPool.execute(new Runnable() { @Override
public void run() {
for(int j=1; j<=2; j++){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("任务[" + taskNum + "]使用线程[" + Thread.currentThread().getName() + "]循环打印数据:" + j);
}
} });//end execute(..);
}//end for(var i) //如果线程中任务执行完毕,没有任务需要执行了,就关闭线程池,如果不关闭,程序就不会结束,而是持续等待新的任务.
threadPool.shutdown();
}
}
传统的实现方式以及上面的线程实现方式都不可能有返回值.在ExecutorService中定义了系列的submit(xxx)方法,该方法可以返回Future<V>接口,通过调用其V get() throws InterruptedException, ExecutionException;就可以获取到线程执行结果.submit可以传滴一个Runnable接口的实现类,也可以传递一个Callable接口的实现类.
Callable接口的实现类[JDK源码引入]
public interface Callable<V> {
V call() throws Exception;
}
说明:Future<V>代表一个异步执行的操作,通过get()方法可以获得操作的结果,如果异步操作还没有完成,则get()会使当前线程阻塞,直到计算完成.
编写5.0新线程的步骤
1.先写一个Callable的子类,然后实现call()方法.
2.调用Executors.newXXThreadPool()返回ExecutorService类型.
3.调用ExecutorService中的submit(Callable的子类)方法启动线程.
4.只有调用ExecutorService的shutdown()方法才能真正的离开虚拟机.
import java.util.concurrent.*; public class ExecutorTest implements Callable { @SuppressWarnings("unchecked")
public static void main(String[] args) throws Exception {
//创建缓存线程池
ExecutorService pool = Executors.newCachedThreadPool();
//指定线程,获取线程返回结果
Future returnV = pool.submit(new ExecutorTest());
//获取线程返回结果
System.out.println("" + returnV.get().toString()); //关闭线程池
pool.shutdown();
} @Override
public Object call() throws Exception {
for(int i=1; i<=5; i++){
Thread.sleep (500);
System.out .println(Thread.currentThread().getName()+" print value " +i);
}
return "Multiple Thread Implements Callable";
}
}
该接口扩展了Executor接口,并声明了许多方法用于管理Executor的声明周期
转载请注明出处:[http://www.cnblogs.com/dennisit/p/3690378.html]
面试求职中需要了解的Java多线程知识的更多相关文章
- JAVA多线程知识总结(二)
本文是承接上一篇文章:JAVA多线程知识总结(一) 四.Java多线程的阻塞状态与线程控制 上文已经提到线程阻塞的集中具体类型.下面主要看引起JAVA线程阻塞的方法 1,join()-----让一个 ...
- JAVA 多线程知识总结(一)
一,线程的生命周期以及五种基本状态 关于JAVA线程的生命周期,首先看一下下面这张图 上图中基本上囊括了Java中多线程各重要知识点.掌握了上图中的各知识点,Java中的多线程也就基本上掌握了. Ja ...
- 面试求职中你需要了解的Java面向对象
从毕业到现在,笔试过好多场 也面了好多场, 一直想写一些东西给找工作的朋友,这篇文章结合个人经历讲解面试中的面向对象.里边有些实例个人以面试题的形式写出来,从程序角度去b帮助大家了解学习,最后希望大家 ...
- 阿里面试官:你连个java多线程都说不清楚,我招你进来干什么
创建线程的方法 继承Thread类 继承Thread类,重写run方法,通过线程类实例.start()方法开启线程. public class TestThread1 extends Thread{ ...
- Java多线程知识整理
多线程 1. 多线程基础 多线程状态转换图 普通方法介绍 yeild yeild,线程让步.是当前线程执行完后所有线程又统一回到同一起跑线.让自己或者其他线程运行,并不是单纯的让给其他线程. join ...
- Java多线程知识总结(一)
一.创建线程的三种方式: 创建线程的方式有三种,一是创建Thread实例,二是实现Runnable接口,三是实现Callable接口,Runnable接口和Callable接口的区别是一个无返回值,一 ...
- Java多线程知识-Callable和Future
Callable和Future出现的原因 创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable接口. 这2种方式都有一个缺陷就是:在执行完任务之后无法获取执行结果. 如果需 ...
- java多线程知识汇总(三)如何选择锁?如何加锁
1.锁,保证的是被锁的代码,一次执行完毕才能被其他线程执行,锁保证了一个线程执行过程中不被其他线程打断.以保证数据的准确性. 2.数据的读写过程,是有冲突的,当一个线程正在读数据,另一个线程正在写同一 ...
- java多线程知识回顾(笔记)
线程创建的方式 有两种 第一种是继承Thread类 重写run方法 (个人偏向这一种实际中这种用的较多) 例如 public class MyThead extends Thread { int j= ...
随机推荐
- hdu 2196 computer
Computer Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
- HDU 5410 CRB and His Birthday(完全背包变形)
CRB and His Birthday Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Oth ...
- 构建ASP.NET网站十大必备工具(2)
正常运行时间 当一个网站发布以后,你肯定希望你的网站不会遇到任何问题,一直处在正常运行状态之中.现在,我使用下面这些工具来监控“Superexpert.com”网站,确保它一直处在正常运行状态之中. ...
- OA 办公自动化系统:权限管理模块的实现原理思路
OA系统分有许多的模块,如系统管理模块.等一些比较高级的业务操作.此类业务是不允许让普通员工来操作的,思路如下: 给系统添加角色表,每个用户对应一个角色,每个角色可以拥有多个权限, 如下:创建权限表( ...
- Groovy basic
1. print println "Hello Groovy!" you can use java in Groovy System.out.println("Hello ...
- iOS /* */多个嵌套解决
解决办法 #if 0 /* */ #endif
- nyoj 737 石子合并(一)。区间dp
http://acm.nyist.net/JudgeOnline/problem.php?pid=737 数据很小,适合区间dp的入门 对于第[i, j]堆,无论你怎么合并,无论你先选哪两堆结合,当你 ...
- extjs,清空treepanel数据。
extjs,清空treepanel数据. //调用 var rootNode = tree.getRootNode(); removeChildrenData(rootNode); //清理节点的数据 ...
- ContentProvider 增删改查通讯录
一.通讯录应用介绍 通讯录应用是Android自带的应用程序,我们看到此应用的时候,可能只认为这是一个应用,用数据库存储数据,但是实际上不是这样的. 通讯录是ContentProvider的应用,通讯 ...
- [转] mhvtl虚拟磁带库的安装与应用
转自:candon123 -- http://candon123.blog.51cto.com/704299/388192/ 1.获取mhvtl: 官方网站:http://mhvtl.nimsa.u ...