【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) 版权声明:本文为博主原创文章,未经博 ...
随机推荐
- 如何开发由Create-React-App 引导的应用(一)
此文章是翻译How to develop apps bootstrapped with Create React App 官方文档 系列文章 如何开发由Create-React-App 引导的应用 如 ...
- HDU 1242 Rescue(优先队列)
题目来源: http://acm.hdu.edu.cn/showproblem.php?pid=1242 题目描述: Problem Description Angel was caught by ...
- nodejs学习笔记 —— 异步编程解决方案
在js或者node编程中,由于异步的频繁和广度使用,使得回调和嵌套的深度导致编程的体验遇到一些挑战,如果写出优雅和好看的代码,本文主要针对异步编程的主流方案做一些总结 1.事件发布/订阅模式 事件监听 ...
- Android回顾系列——之HttpUrlConnect的使用
写在前面: 最近准备一个关于Android的比赛.由于赛项要求,不得使用第三方工具.框架:故最近来温习一下Google官方提供的原始API的使用. 说实话,用惯了第三方的库,再回过头来用原生的api的 ...
- IDEA for Mac注册码使用
尼玛,一不注意把磁盘抹掉了,重新下idea发现 之前的破解方法失效了 之前所有的 idea 授权服务器已遭JetBrains封杀,所以重新下载后 用之前的方法已经然并卵了,苦苦google后,发现新大 ...
- python写一个防御DDos的脚本(请安好环境否则无法实验)
起因: 居然有ddos脚本,怎么可以没防御ddos的脚本! 开始: 1.请执行 install.py安装好DDos-defalte,会在root目录下多出这个文件夹 代码: 2.然后执行fyddos. ...
- mysql中使用show table status 查看表信息
本文导读:在使用mysql数据库时,经常需要对mysql进行维护,查询每个库.每个表的具体使用情况,Mysql数据库可以通过执行SHOW TABLE STATUS命令来获取每个数据表的信息. 一.使用 ...
- 【WebApi系列】浅谈HTTP
[01]浅谈HTTP在WebApi开发中的运用 [02]聊聊WebApi体系结构 [03]详解WebApi如何传递参数 [04]详解WebApi测试和PostMan [05]浅谈WebApi Core ...
- NSDateFormatter相关整理
//实例化一个NSDateFormatter对象NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init]; //设定时间格式,这里可 ...
- This is probably because there is no OLE editor registered against the type of file you were trying to open.
Reason: This is probably because there is no OLE editor registered against the type of file you were ...