java线程实现的三种方式
来源:互联网 发布:鲁能泰山 网络直播 编辑:程序博客网 时间:2024/05/22 05:07
Java中线程的实现方式有如下三种:
1.继承Thread类
public class Thread extends Object implements Runnable
定义Thread类的子类,并重写Thread类的run()方法,创建子类对象(即线程对象),调用线程对象的start()方法来启动该线程。
/**
* @Description:
* @author WEISANGENG
* @date 2017年3月3日
*/
public class ThreadDemo extends Thread {
private int i;
/**
* @功能描述: Thread线程的方式
*
* @date 2017年3月3日
* @author WEISANGENG
*/
@Override
public void run() {
for (; i < 100; i++) {
System.out.println(getName() + " " + i);
}
}
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
// currentThread是Thread类的静态方法,该方法返回当前正在执行的线程对象
// getName()返回当前线程对象的名字
System.out.println(Thread.currentThread().getName() + " " + i);
if (i == 20) {
// 启动两个线程,但是实际上有三个线程,即main主线程
// 用户启动的多个线程的名字依次为Thread-0、Thread-1、、、、
new ThreadDemo().start();
new ThreadDemo().start();
}
}
}
}
/*注意:该例中第一次出现的变量i是实例变量,而每次创建线程对象时候,Thread-0和Thread-1两个线程对象不能共享实例变量i。
即使用继承Thread方法创建线程对象时,多个线程之间无法共享线程类的实例变量。*/
2.实现Runnable接口
public interface Runnable
定义Runnable接口的实现类,并重写该接口的run()方法,该run()方法同样是该线程的执行体。创建该Runnable实现类的实例,并将此实例作为Thread的target(即构造函数中的参数)来创建Thread对象(该Thread对象才是真正的线程对象,只是该Thread对象负责执行其target的run()方法)。最后调用线程对象的start()方法来启动该线程。
/**
* @Description: TODO(用一句话描述该文件做什么)
* @author WEISANGENG
* @date 2017年3月3日
*/
public class RunnableDemo implements Runnable {
private int i;
@Override
public void run() {
for (; i < 100; i++) {
// 当线程类实现Runnable接口时,只能通过Thread.currentThread()方法获得当前线程
System.out.println(Thread.currentThread().getName() + " " + i);
}
}
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
if (i == 20) {
ThreadDemo td = new ThreadDemo();
// 创建两个Thread对象,并且均把Runnable接口实例对象作为target
new Thread(td).start();
new Thread(td).start();
}
}
}
}
3.使用Callable和Future
Executor是Java线程池的顶级接口
备注:ScheduledExecutorService描述的功能和Timer/TimerTask类似,解决那些需要任务重复执行的问题。这包括延迟时间一次性执行、延迟时间周期性执行以及固定延迟时间周期性执行等。当然了继承ExecutorService的ScheduledExecutorService拥有ExecutorService的全部特性。
Executors是一个类
Executors类提供了若干个静态方法,用于生成不同类型的线程池:
/**
* @Description: 启动一个任务,然后等待任务的计算结果,如果等待时间超出预设定的超时时间,则中止任务。
* @author WEISANGENG
* @date 2017年3月3日
*/
public class ExecutorServiceTest {
public static void main(String[] args) {
System.out.println("Start ...");
//创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需要的线程,
//那么就会回收部分空闲(60秒不执行任务)的线程,当任务数增加时,此线程池又可以智能的添加新线程来处理任务。
//此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。
ExecutorService exec = Executors.newCachedThreadPool();
//testTask(exec, 15); // 任务成功结束后等待计算结果,不需要等到15秒
testTask(exec, 5); // 只等待5秒,任务还没结束,所以将任务中止
exec.shutdown();
System.out.println("End!");
}
public static void testTask(ExecutorService exec, int timeout) {
MyTask task = new MyTask();
//提交一个返回值的任务用于执行,返回一个表示任务的未决结果的 Future。
//该 Future 的 get 方法在成功完成时将会返回该任务的结果。
Future<Map<String, Object>> future = exec.submit(task);
Map<String, Object> taskResult = null;
String failReason = null;
try {
// 等待计算结果,最长等待timeout秒,timeout秒后中止任务
taskResult = future.get(timeout, TimeUnit.SECONDS);
} catch (InterruptedException e) {
failReason = "主线程在等待计算结果时被中断!";
} catch (ExecutionException e) {
failReason = "主线程等待计算结果,但计算抛出异常!";
} catch (TimeoutException e) {
failReason = "主线程等待计算结果超时,因此中断任务线程!";
}
exec.shutdownNow();
System.out.println("\ntaskResult : " + taskResult);
System.out.println("failReason : " + failReason);
}
}
/**
*
* @Description: 任务器
* @author WEISANGENG
* @date 2017年3月3日
*/
class MyTask implements Callable<Map<String, Object>> {
@Override
public Map<String, Object> call() throws Exception {
// 总计耗时约10秒
for (int i = 0; i < 10; i++) {
Thread.sleep(1000); // 睡眠1秒
System.out.println("第"+(i+1)+"秒");
}
Map<String, Object> map = new HashMap<String, Object>();
map.put("key", "weisg81");
return map;
}
}
- java线程的三种实现方式
- Java线程实现的三种方式
- java线程实现的三种方式
- JAVA中实现线程的三种方式
- 黑马程序员-java基础-三种实现线程的方式
- Java基础学习之实现线程的三种方式
- Java中线程的三种实现方式
- java创建线程的三种实现方式
- 线程实现的三种方式
- 线程的三种实现方式
- 线程同步的三种实现方式
- java的线程的三种方式
- java创建线程的三种方式
- java创建线程的三种方式
- Java创建线程的三种方式
- Java线程创建的三种方式
- Java创建线程的三种方式
- Java创建线程的三种方式
- js基础--数据类型转换
- 使用Dev-C++查看vector数组中的变量值
- 烈酒的博客
- LeetCode 524. Longest Word in Dictionary through Deleting
- LeetCode 530. Minimum Absolute Difference in BST
- java线程实现的三种方式
- hibernate中的update()和saveOrUpdate()的区别,session的load()和get()的区别。
- opencv学习笔记(二十九)绘制一个RGB三色直方图
- [JAVA]数组转换成字符串
- Linux gcc编译器
- Macos系统下PATH环境变量的配置方法
- 蓝桥杯 ALGO-98 算法训练 数位分离
- String,StringBuffer与StringBuilder之间区别
- hadoop hbase 问题 及 简单 案例