Java 范例 - 线程
创建线程
Java 中有以下三种方式创建线程,其中前两种无法获取返回值,而最后一种可以获取返回值。
- 实现 Runnable 接口
- 继承 Thread 类
- 通过 Callable、Future 接口配合
实现 Runnable 接口
可以声明一个类实现 Runnable 接口,接着在重写的 run()
方法中编写线程中执行的代码。
class RunnableThread implements Runnable {
@Override
public void run() {
// ...
}
}
接着实例化该类,并作为 Thread
类的构造器参数传入。
Thread runnableThread = new Thread(new RunnableThread());
继承 Thread 类
与实现 Runnable 接口相同,继承也需要重写 run()
方法。
class ExtendThread extends Thread {
@Override
public void run() {
// ...
}
}
不过这种方式创建线程,直接实例化类就可以了。
Thread extendThread = new ExtendThread();
通过 Callable、Future 接口配合
先声明一个类继承 Callable 接口,其中接口中的泛型为返回值的类型,线程中的执行代码在重写的 call()
方法中。
public class ReturnThread implements Callable<String> {
@Override
public String call() {
// ...
return "return value";
}
}
实例化该类,将其提交到线程池(线程池篇会提及)中运行,然后可以通过 get()
方法来获取返回值。
Callable<String> returnThread = new ReturnThread();
Future<String> returnValue = executor.submit(returnThread);
returnValue.get();
FutureTask 类
当通过 submit()
方法向线程池提交任务时,当前线程会阻塞直到返回结果,为了满足不阻塞的需求就有了 FutureTask 类。将上面继承 Callable 接口的类用 FutureTask 类包装后,在提交至线程池中运行。
由于 FutureTask 类实现了 RunnableFuture 接口,而 RunnableFuture 接口继承了 Runnable 和 Future 接口,所以也可以用 get()
方法来获取返回值。
FutureTask<String> futureTask = new FutureTask<>(returnThread);
executor.submit(futureTask);
// Unblock, so can do something here
futureTask.get();
线程的状态及转换
Java 线程有以下七种状态,但除去创建状态和终止状态,就只有和操作系统课程中进程一样的三类状态,分别是就绪、运行和阻塞。
- 创建状态(new),线程创建完毕
- 就绪状态(runnable),线程所需资源准备完毕
- 运行状态(running),线程获得处理机时间
- 终止状态(dead),线程执行完毕或异常中断
- 阻塞状态(blocked),线程被同步阻塞或者 IO 阻塞
- 超时等待(time waiting),线程主动睡眠指定时间
- 等待阻塞(waiting),线程主动等待
上文创建线程例子中(除开线程池提交例子),当用 new
关键字创建好线程后,线程就进入了创建状态,可以用 start()
方法让线程进入就绪状态(前提是线程所需资源准备完毕),接着就可以等待的调度进入运行状态,然后线程运行完之后进入终止状态。
当线程遇到同步或者 IO 时就会进入阻塞状态,调用 join()
方法可以让线程主动等待另一线程线程执行完毕,而线程中调用 sleep()
方法就可以让线程主动睡眠指定的一段时间,以下为线程状态转换状态图。
new --> runnable <---> running --> dead
| ^
| |
*---> blocked ---*
| |
| |
*---> waiting ---*
| |
| |
*-> time waiting *
Thread 类常用方法
下面列出了 Thread 类中常用的方法。
// 让线程进入就绪状态
start()
// 线程主动睡眠指定时间
sleep(long millis)
sleep(long millis, int nanoseconds)
// 线程让出处理机时间,给同优先级的线程
// 注意该方法让线程重回就绪状态,而不是阻塞状态
yield()
// 等待线程执行完毕,或者等待指定时间
join()
join(long millis)
join(long millis, int nanoseconds)
// 中断处于阻塞状态的线程,注意不能中断正在运行中的线程
interrupt()
// 获取线程标识符
getID()
// 获取设置线程名称
getName()
setName()
// 获取设置线程优先级
getPriority()
setPriority()
// 设置线程是否为守护线程
setDaemon()
// 判断是否为守护线程
isDaemon()
Java 范例 - 线程的更多相关文章
- java基础—线程(一)
一.线程的基本概念
- java之线程
java之线程 一:线程: 线程是什么呢?线程,有时被称为轻量级进程是程序执行流的最小单元.一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成.另外,线程是进程中的一个实体,是被系统 ...
- Java 使用线程方式Thread和Runnable,以及Thread与Runnable的区别
一. java中实现线程的方式有Thread和Runnable Thread: public class Thread1 extends Thread{ @Override public void r ...
- Java的线程安全
线程安全 我们这里讨论的线程安全,就限定于多个线程之间存在共享数据访问这个前提,因为如果一段代码根本不会与其他线程共享数据,那么从线程安全的角度来看,程序是串行执行还是多线程执行对它来说是完全没有区别 ...
- 深入理解Java之线程池
原作者:海子 出处:http://www.cnblogs.com/dolphin0520/ 本文归作者海子和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则 ...
- java中线程分两种,守护线程和用户线程。
java中线程分为两种类型:用户线程和守护线程. 通过Thread.setDaemon(false)设置为用户线程: 通过Thread.setDaemon(true)设置为守护线程. 如果不设置次属性 ...
- java 多线程—— 线程让步
java 多线程 目录: Java 多线程——基础知识 Java 多线程 —— synchronized关键字 java 多线程——一个定时调度的例子 java 多线程——quartz 定时调度的例子 ...
- java 多线程—— 线程等待与唤醒
java 多线程 目录: Java 多线程——基础知识 Java 多线程 —— synchronized关键字 java 多线程——一个定时调度的例子 java 多线程——quartz 定时调度的例子 ...
- Java的线程模型
并发不一定要依赖多线程(如PHP中很常见的多进程并发),但是在Java里面谈论并发,大多数都与线程脱不开关系. 线程是比进程更轻量级的调度执行单位,线程的引入,可以把一个进程的资源分配和执行调度分开, ...
随机推荐
- C#控件之:进度条(ProgressBar)
一.重绘进度条 public class CustomProgressBar:ProgressBar { public CustomProgressBar() { this.SetStyle(Cont ...
- 关于latex的网站推荐
有时候,你不知道某个数学符号的tex写法是什么,可以在下面这个网站手写该符号,然后会出现很多候选. http://detexify.kirelabs.org/classify.html 用latex处 ...
- (转)C# 中使用分布式缓存系统Memcached
转自:http://blog.csdn.net/devgis/article/details/8212917 缘起: 在数据驱动的web开发中,经常要重复从数据库中取出相同的数据,这种重复极大的增加了 ...
- 20145232 韩文浩 《Java程序设计》第10周学习总结
13.1 网络概述 13.1.1计算机网络概述 网络编程的实质:两个(或多个)设备(例如计算机)之间的数据传输. 计算机网络的定义:通过一定的物理设备将处于不同位置的计算机连接起来组成的网络,这个网络 ...
- 51nod 1239 欧拉筛模板
#include<iostream> #include<cmath> #include<cstring> #include<cstdio> #inclu ...
- 普通用户开放 sudo 权限
大家都知道 linux 每个目录都是有权限的,所以如果要想在此目录下读写,则要有这个目录的权限,或者就是有 sudo 权限,那怎么给普通用户赋予 sudo 权限呢,下面我们来看一下: 1.先用 roo ...
- SRM473
250pt: 题意:在二维平面上,给定3种,左转.右转,以及前进一步,的指令序列循环执行,问整个移动过程是否是发散的. 思路:直接模拟一个周期,然后判断1.方向是否和初始时不同 2.是否在原来的点 满 ...
- unigui验证微信服务器的有效性
UNIGUI验证微信服务器的有效性: //////////////////////////////////////////// //UniGUIServerModuleHTTPCommand //公众 ...
- Android-WebView与本地HTML (HTML调用-->Java的方法)
上一篇博客 Android-WebView加载网络图片&网页 介绍了 使用WebView去加载网络上的图片与网页; 此篇博客专门介绍 Android-WebView与本地HTML (HTML调 ...
- 提示 make: 没有什么可以做的为 `all'
提示 make: 没有什么可以做的为 `all'. make clean 一次,编译过程又有了.