Java 并发的初步学习 (Thread的 Runnable Callable 试用)

来源:互联网 发布:淘宝买汽枪怎么搜索 编辑:程序博客网 时间:2024/06/05 08:37

Java并发机制(即多线程)的初步学习笔记

 

1.      学习从runnable的run函数重载开始,照抄了一份样例代码,希望能从中发现问题

 

../LiftOff.java

 

../BasicThreads.java

 

输出:

 

A)     随着阅读的深入,发现了第一个问题,在上面的输出中,一句“Waiting for LiftOff” 的优先出现引起了我的注意,希望能够得到解释。

参考书中解释,简单的说就是先到谁,谁就输出。 这种先来先干的策略在这段代码中就体现为: t.start() 代码开始执行LiftOff() 中 while(countdown--- > 0){}的代码之前,已经执行到了BasicThreads主函数里System.out.println这句,所以就先输出来了!

 

之后,又抄了一段循环多线程创建及执行的代码

输出:

截取的图片不是很完整,后面的输出没截图截完整! 但是可以很清楚地看到,输出的变化多端根源还是先到谁 谁先来!

这个原则就到这里后面不再做证明了。

不过,这也可以引出:线程调度机制是非确定性的。

 

B)         线程的调度已经实现了,LiftOff暴露了要执行的但一方法,这就是用“命令”设计模式。这时候我就需要一个Service能够知道如何去构建上下文来执行Runnable对象。

这里就引出了ExecutorService类。

 

下面想构建的一个ExecutorService对象是完成一个线程后再执行下一个线程:

为了简洁明了,吧原先countDown = 10的初始值改成3 ,这样run()里面的while循环就少转几圈,输出也能更清楚点

../LiftOff.java

 

../SingleThreadExecutor.java

输出:

 

小结可以看到,每一个线程都是执行完之后才跳出的!

ExecutorService对象是用静态的Executor方法创建的,这个方法可以确定对象其Executor的类型。(Executor里定义了不同种类型)

 

2.      Callable的学习进行下去。

Callable能在任务完成时能够返回一个值的接口。类型参数的表示是从方法call() 中返回的值,并且必须用ExecutorService.submit()方法调用。

Callable里面会接触到一些新的东西,如Future对象:他用Callable返回结果的特定类型进行了参数化;可以使用isDone()方法来查询Future是否已完成;或者直接使用get(),在这种情况下,get()将阻塞,直至结果准备就绪。

 

在尝试代码的时候发现Callable<String>可以通过,但是Callable<int> 会报错

先用<Callable>String写个样例

 

../TaskGetNumber.java

 

../CallableGetNumber.java

 

输出:

 

小结: Callable接口,使用ExecutorService接受Callable对象并经由

<T> Future<T> submit(Callable<T> task)  方法执行。 然后会返回一个Future对象,Future<T>的get方法将会阻塞,直到任务完成。

 

 

3.      操作系统里,线程的优先级问题很重要,事关资源抢占的问题,那么就来看看java是怎么区分优先级的

测试代码,创建不同优先级的线程,观察执行顺序。

../SimplePriorities.java

 

 

输出:

 

可以清楚的发现,原本最后执行的task3线程,由于优先级被调高后,优先执行了!


原创粉丝点击