博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【技术交流】让我们来谈一谈多线程和并发任务
阅读量:6584 次
发布时间:2019-06-24

本文共 3270 字,大约阅读时间需要 10 分钟。

相信你已经了解过多线程的概念,不妨咱们来回顾下,做个暖场如何

相关概念

  • 线程、进程  

    依赖包含关系、相似(状态)、区别(内存共享、资源共享、成本)

    进程是操作系统分配资源的基础单位,而线程是CPU执行的基础单位

    线程与线程间是并列且独立的。

  • 线程空间、ThreadLocal、线程上下文

    线程运行时所占用的内存、锁、cpu等资源的一个虚拟视图

    线程的一个局部变量,可以理解为与当前线程绑定的一个map

    线程空间的一个实时状态

  • 线程状态

    创建、运行、阻塞、销毁

  • 线程与锁

    加锁是为了同步调度

    锁的类型:共享锁、互斥锁;只读锁、可写锁
    死锁
    争夺资源
    调度失当

线程并发模型

  • 阻塞队列

    当队列不满足操作条件时,操作线程将进入阻塞状态
    get()时,如果队列为空,则阻塞线程,直到成功执行了add()
    add()时,如果队列已满,则阻塞线程,直到成功执行了get()
    最常用的一种并发调度器

    eg :生产者-消费者

  • 闭锁

    闭锁线程转换到“开门”状态之前,任何尝试“进门”的线程都会被阻塞

    eg:登机

  • 关卡

    所有线程都执行到“关卡”点之前,任何尝试“过关”的线程都会被阻塞

    eg:大巴车

线程实现

java多线程实现,有两种方法。继承Thread,实现接口Runable。大多数时候我们采用后者。原因很简单:单继承,多实现,况且java的设计原则有一条是“面向接口编程”。

测试类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public
class
TestMain {
@Test
public
void
testThread(){
//
Thread th1 = 
new
TestNoSynThread();
Thread th2 = 
new
TestNoSynThread();
th1.start();
th2.start();
}
@Test
public
void
testRunable(){
//
TestNoSynRunable r = 
new
TestNoSynRunable();
Thread th1 = 
new
Thread(r,
"thread-a"
);
Thread th2 = 
new
Thread(r,
"thread-b"
);
th1.start();
th2.start();
}
}

注:start方法只是启动线程,使线程处于可运行状态,并没有运行。一旦得到cpu,就开始执行重写的run方法。run执行完毕,线程结束。

下面再来介绍并发实现的另一种方式,实际上是Runable方式上的封装。在JDK1.5出现之后,Sun发布的多线程并发处理的工具包

java.util.concurrent

  • Executor

    并发任务执行器的顶级抽象,只针对Runnable

  • ExecutorService 

    对Executor进行扩展,支持Callable和Future

  • Callable

    对Runnable进行扩展,提供了返回值。

  • Future

    阻塞线程,直到Callable返回了值

  • FutureTask

    实现了Callable和Future
    可以简单理解为同时是生产者和消费者的类

  • 其它

    闭锁、关卡等实现

并发任务使用

声明一个ExecutorService 
向ExecutorService 提交一个或多个Callable,并获取Future
从Future中获取Callable的返回结果
项目应用
实际上是一个“大巴车”模型

测试类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public
class
TestExecutorService {
private
int
SIZE = 
10
;
/**
* 计算1+2+...+100.
*
* @author wuyichen-ghq
* @since 2013-12-31
*/
@Test
public
void
main() {
ExecutorService exeService = Executors.newCachedThreadPool();
// 任务列表,分成1+10、11+20、。。。、91+100
List<FutureTask<Integer>> taskList = 
new
ArrayList<FutureTask<Integer>>(
SIZE);
for
(
int
i = 
0
; i < SIZE; i++) {
TestFutureTask task = 
new
TestFutureTask(i * 
10
1
, (i + 
1
) * 
10
);
taskList.add(
new
FutureTask<Integer>(task));
}
// 逐个提交任务(这里可以将任务创建和提交放在一个for里)
for
(FutureTask<Integer> task : taskList) {
exeService.submit(task);
}
// 逐个获取任务结果
FutureTask<Integer> task = 
null
;
// 任务序列号
int
taskIndex = 
0
;
try
{
while
(taskIndex < taskList.size()) {
task = taskList.get(taskIndex);
assert
task != 
null
;
int
result = task.get();
System.out.println(result);
taskIndex++;
}
catch
(InterruptedException e) {
e.printStackTrace();
catch
(ExecutionException e) {
e.printStackTrace();
}
}
}

task类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public
class
TestFutureTask 
implements
Callable<Integer>{
private
int
begin;
private
int
end;
/**
* TODO:(构造方法描述)
*
* @author wuyichen-ghq
* @since 2013-12-31
* @param i
*/
public
TestFutureTask(
int
begin,
int
end) {
this
.begin = begin;
this
.end = end;
}
/**
* TODO:(方法描述)
*
* @author wuyichen-ghq
* @since 2013-12-31
* @throws 无
* @see java.util.concurrent.Callable#call()
*
*/
@Override
public
Integer call() 
throws
Exception {
int
result = 
0
;
for
(
int
i=begin;i<=end;i++){
result = i + result;
}
return
result;
}
}

要注意的地方:

异常处理

ExecutorService有两个方法:submit、execute

that's all!如果文章中什么错误,请与我联系,也欢迎您跟我邮件交流哦!

邮箱:wyc_job@163.com

本文出自 “” 博客,请务必保留此出处

转载地址:http://xxano.baihongyu.com/

你可能感兴趣的文章
hook的本质就是在本愿可执行文件中加东西
查看>>
归档日志路径
查看>>
Spring中基于Java的配置@Configuration和@Bean用法
查看>>
用thinkphp开启伪静态,用wamp开启很快搞定;但是用phpstudy总是开启失败,为什么?...
查看>>
DevExpress 只允许修改指定列
查看>>
Java的静态导入
查看>>
七、Framework类库
查看>>
Java继承是复制还是共用?答案共用
查看>>
年终的团队公开信
查看>>
Python循环语句
查看>>
[转] http chunk
查看>>
线索二叉树
查看>>
关于时区的时间的详解,比如UTC\GMT等
查看>>
C#实现的三种方式实现模拟键盘按键
查看>>
洛谷P3327 [SDOI2015]约数个数和(莫比乌斯反演)
查看>>
java 堆和栈一般理解
查看>>
解决PLSQL Developer 插入中文 乱码问题(转)
查看>>
使用 SVN Hook 实现服务器端代码自动更新
查看>>
最炫数学风
查看>>
python 高阶函数 map lambda filter等
查看>>