【Java】多线程初探
Java的线程状态

- getState方法:返回该线程的状态,可能是NEW, RUNNABLE, BLOCKED, WAITING, TIME_WAITING, TEMINATED之一
- getName: 返回线程名称
- getPriority: 返回线程优先级
public class MyThread extends Thread{
@Override
public void run() {
System.out.println("线程状态:" + Thread.currentThread().getState());
System.out.println("线程名称:" + Thread.currentThread().getName());
System.out.println("线程优先级:" + Thread.currentThread().getPriority());
}
public static void main (String args []) {
MyThread t = new MyThread();
t.start();
}
}
输出:
线程状态:RUNNABLE
线程名称:Thread-0
线程优先级:5
线程的创建和启动
一. 继承Thread类创建线程
public class MyThread extends Thread {
private int i = 0;
public void run () {
i++;
System.out.println(i);
}
public static void main (String args []){
MyThread t = new MyThread();
t.start();
}
}
1
二. 实现Runnable接口创建线程
public class MyRunnable implements Runnable {
private int i =0;
@Override
public void run() {
i++;
System.out.println(i);
}
}
Test.java
public class Test {
public static void main (String args[]) {
Thread t = new Thread(new MyRunnable());
t.start();
}
}
输出
1
三. 通过Callable接口和Future接口创建线程
public interface Future<V> {
V get () throws ...; // 当任务完成时, 获取结果
V get (long timeout, TimeUnit unit); // 在get方法的基础上指定了超时时间
void cancel ( boolean mayInterupt); // 取消任务的执行
boolean isDone (); // 任务是否已完成
boolean isCancel (); // 任务是否已取消
}
- 对于Callable对象来说, Future对象可帮助它保存结果信息,当调用get方法的时候将会发生阻塞, 直到结果被返回。
- 而对于Runnable对象来说, 无需保存结果信息, 所以get方法一般为null, 这里Future的作用主要是可以调用cancel方法取消Runnable任务
FutureTask task = new FutureTask(new Callable);
得到的task既是一个Runnable也是一个Future。这样一来,可以先把得到的task传入Thread构造函数中创建线程并运行(作为Runnable使用), 接着通过task.get以阻塞的方式获得返回值(作为Future使用)
import java.util.concurrent.Callable;
public class MyCallable implements Callable {
@Override
public Object call() throws Exception {
Thread.sleep(1000);
return "返回值";
}
}
Test.java
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class Test {
public static void main (String args []) throws ExecutionException, InterruptedException {
// task同时实现了Runnable接口和Future接口
FutureTask task = new FutureTask(new MyCallable());
// 作为 Runnable 使用
Thread t = new Thread(task);
t.start();
// 作为Future使用, 调用get方法时将阻塞直到获得返回值
System.out.println(task.get());
}
}
返回值
四.通过线程池创建和管理线程
public interface Executor {
void execute(Runnable command);
}
public interface ExecutorService extends Executor {
void shutdown();
<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);
// 其他方法
}
- 调用submit方法可以将Runnable或Callable实例提交给线程池里的空闲线程执行,同时返回一个Future对象, 保存了和执行结果有关的信息
- 当线程池用完时, 需要调用 shutdown方法关闭线程
public class Executors {
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());
}
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
}
}

public class MyRunnable implements Runnable{
@Override
public void run() {
for (int i=0;i<3;i++) {
System.out.println("MyRunnable正在运行");
}
}
}
import java.util.concurrent.Callable;
public class MyCallable implements Callable{
@Override
public Object call() throws Exception {
for (int i=0;i<3;i++) {
System.out.println("MyCallable正在运行");
}
return "回调参数";
}
}
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Test {
public static void main (String args []) throws ExecutionException, InterruptedException {
// 创建一个固定数量为2的线程池
ExecutorService service = Executors.newFixedThreadPool(2);
// 向线程池提交Callable任务,并将结果信息保存到Future中
Future callableFuture = service.submit(new MyCallable());
// 向线程池提交Runnable任务,并将结果信息保存到Future中
Future runnableFuture = service.submit(new MyRunnable());
// 输出结果信息
System.out.printf("MyCallable, 完成:%b取消:%b返回值:%s%n", callableFuture.isDone(),
callableFuture.isCancelled(), callableFuture.get());
System.out.printf("MyRunnable, 完成:%b取消:%b返回值:%s%n", runnableFuture.isDone(),
runnableFuture.isCancelled(), runnableFuture.get());
// 关闭线程池
service.shutdown();
}
}
MyCallable正在运行
MyCallable正在运行
MyCallable正在运行
MyCallable, 完成:true取消:false返回值:回调参数
MyRunnable正在运行
MyRunnable正在运行
MyRunnable正在运行
MyRunnable, 完成:false取消:false返回值:null
线程的运行
线程的阻塞(广义)
- 阻塞(Blocked)是试图获得对象锁(不是java.util.concurrent库中的锁),而对象锁暂时被其他线程持有导致
- 等待(Waiting)则是调用Object.wait,Thread.join或Lock.lock等方法导致的
- 计时等待(Time waiting)则是在等待的方法中引入了时间参数进入的状态,例如sleep(s)
线程的终止
1. 共享变量结束线程
public class InteruptSimulation implements Runnable{
private volatile static boolean stop = false;
@Override
public void run() {
try {
while (!stop) {
System.out.println("线程正在运行");
// 休眠5秒
Thread.sleep(5000);
}
System.out.println("线程终止");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main (String args []) throws InterruptedException {
Thread t = new Thread(new InteruptSimulation());
t.start();
// 休眠1秒
Thread.sleep(1000);
// 将共享变量stop置为true
System.out.println("发出终止线程的信号");
stop = true;
}
}
线程正在运行
发出终止线程的信号
// 约5s后输出
线程终止
2. 利用中断机制结束线程
public class InteruptReal implements Runnable{
@Override
public void run() {
try {
while (!Thread.currentThread().isInterrupted()) {
System.out.println("线程正在运行");
Thread.sleep(5000);
}
} catch (InterruptedException e) {
// 发生中断异常后,中断状态位会被置为false,这里不做任何操作
}
System.out.println("线程已中断");
}
public static void main (String args []) throws InterruptedException {
Thread t = new Thread(new InteruptReal());
t.start();
// 休眠1s
Thread.sleep(1000);
System.out.println("发出终止线程的信号");
t.interrupt();
}
}
输出:
线程正在运行
发出终止线程的信号
// 立即输出
线程已中断
线程现在已经能够及时退出啦
public class InteruptReal implements Runnable{
@Override
public void run() {
try {
while (!Thread.currentThread().isInterrupted()) {
System.out.println("线程正在运行");
Thread.sleep(5000);
}
} catch (InterruptedException e) {
System.out.println("中断状态位:"+Thread.currentThread().isInterrupted());
}
}
public static void main (String args []) throws InterruptedException {
Thread t = new Thread(new InteruptReal());
t.start();
// 休眠1s
Thread.sleep(1000);
System.out.println("发出中断");
t.interrupt();
}
}
输出:
线程正在运行
发出中断
中断状态位:false
线程的常用方法调用
Thread.sleep
Thread.yeild
Thread.join
public class JoinRunnable implements Runnable{
@Override
public void run() {
for(int i=0;i<3;i++) {
System.out.println(Thread.currentThread().getName()+ "正在执行");
}
}
public static void main (String args[]) throws InterruptedException {
Thread t = new Thread(new JoinRunnable());
t.start();
System.out.println("子线程执行完毕");
}
}
子线程执行完毕
Thread-0正在执行
Thread-0正在执行
Thread-0正在执行
public class JoinRunnable implements Runnable{
@Override
public void run() {
for(int i=0;i<3;i++) {
System.out.println(Thread.currentThread().getName()+ "正在执行");
}
}
public static void main (String args[]) throws InterruptedException {
Thread t = new Thread(new JoinRunnable());
t.start();
t.join();
System.out.println("子线程执行完毕");
}
}
输出:
Thread-0正在执行
Thread-0正在执行
Thread-0正在执行
子线程执行完毕
【Java】多线程初探的更多相关文章
- Java多线程初探
多线程 单线程的程序只有一个顺序执行流.多个顺序流之间互不干扰. 多线程的创建 定义Thread类的子类,重写该类的run()方法. 创建Thread子类的实例. 调用线程对象的start()方法来启 ...
- java并发初探ConcurrentHashMap
java并发初探ConcurrentHashMap Doug Lea在java并发上创造了不可磨灭的功劳,ConcurrentHashMap体现这位大师的非凡能力. 1.8中ConcurrentHas ...
- java并发初探ReentrantWriteReadLock
java并发初探ReentrantWriteReadLock ReenWriteReadLock类的优秀博客 ReentrantReadWriteLock读写锁详解 Java多线程系列--" ...
- 40个Java多线程问题总结
前言 Java多线程分类中写了21篇多线程的文章,21篇文章的内容很多,个人认为,学习,内容越多.越杂的知识,越需要进行深刻的总结,这样才能记忆深刻,将知识变成自己的.这篇文章主要是对多线程的问题进行 ...
- Java多线程基础知识篇
这篇是Java多线程基本用法的一个总结. 本篇文章会从一下几个方面来说明Java多线程的基本用法: 如何使用多线程 如何得到多线程的一些信息 如何停止线程 如何暂停线程 线程的一些其他用法 所有的代码 ...
- Java多线程系列--“JUC锁”03之 公平锁(一)
概要 本章对“公平锁”的获取锁机制进行介绍(本文的公平锁指的是互斥锁的公平锁),内容包括:基本概念ReentrantLock数据结构参考代码获取公平锁(基于JDK1.7.0_40)一. tryAcqu ...
- Java多线程系列--“JUC锁”04之 公平锁(二)
概要 前面一章,我们学习了“公平锁”获取锁的详细流程:这里,我们再来看看“公平锁”释放锁的过程.内容包括:参考代码释放公平锁(基于JDK1.7.0_40) “公平锁”的获取过程请参考“Java多线程系 ...
- Java多线程--让主线程等待子线程执行完毕
使用Java多线程编程时经常遇到主线程需要等待子线程执行完成以后才能继续执行,那么接下来介绍一种简单的方式使主线程等待. java.util.concurrent.CountDownLatch 使用c ...
- Java多线程 2 线程的生命周期和状态控制
一.线程的生命周期 线程状态转换图: 1.新建状态 用new关键字和Thread类或其子类建立一个线程对象后,该线程对象就处于新生状态.处于新生状态的线程有自己的内存空间,通过调用start方法进入就 ...
- java 多线程 1 线程 进程
Java多线程(一).多线程的基本概念和使用 2012-09-10 16:06 5108人阅读 评论(0) 收藏 举报 分类: javaSE综合知识点(14) 版权声明:本文为博主原创文章,未经博 ...
随机推荐
- in运算符(javascript)
in的用法,如x in y: 1.如果第二个运算数为对象,则in运算符用来检测第一个运算数是否是第二个运算数的属性名.是,返回true,否则返回false. 例: var obj = {x:1,y:2 ...
- 从零开始学习前端开发 — 12、CSS3弹性布局
一.分栏布局 1.设置栏数column-count:数值; 2.设置每栏的宽度column-width:数值+单位; 注:当设置了column-width,column-count会失效,二者设置其一 ...
- MySQL时间差返回月个数
select PERIOD_DIFF(date_format(now(),'%Y%m'),date_format('2010-11-30','%Y%m')) 1. MySQL 为日期增加一个时间间隔: ...
- 百度Apollo 尝试
从Git-Hub上下载了Apollo源码在Ubuntu上准备运行一下 完成了以下步骤: bash docker/scripts/install_docker.sh bash docker/script ...
- 安卓开发-intent在Activity之间数据传递
安卓开发-intent在Activity之间数据传递 [TOC] intent实现普通跳转 使用intent的setclass方法,示例(由此界面跳转到NewActivity界面) //使用setOn ...
- spring boot 文件上传 文件过大 FileUploadBase$SizeLimitExceed
application.properties中加入 multipart.maxFileSizemultipart.maxRequestSize Spring Boot 1.3.x或者之前 multip ...
- Overload&Override
Overload&Override overload-–重载 方法的重载就是在一个类中,可以定义多个有相同名字,但参数不同的方法.调用时,会根据不同的参数表选择对应的方法. 规 则:两同 ...
- AI_深度学习为何兴起?
深度学习和神经网络,在此技术背后的理念,已经发展了好几十年了,为何现在流行起来了? 最直接因素: 将帮助你在自己的组织中,发现好机会,来应用这些东西 为什么深度学习这么厉害? x轴表示完成任务的数据数 ...
- MySQL中时间函数NOW()和SYSDATE()的区别
mysql中日期函数还是比较常用的.主要有NOW()和SYSDATE()两种,虽然都表示当前时间,但使用上有一点点区别. NOW()取的是语句开始执行的时间,SYSDATE()取的是动态的实时时间. ...
- 使用EndNote在Word中插入参考文献的格式设置
endnote其实自带了很多参考文献格式的样式,如下图,但往往跟我们要使用的会有所出入,本文主要介绍的就是设置自定义endnote参考文献格式,以endnote X6和word2003为例,其它版本以 ...