JAVA 多线程
多线程的四种方式
继承Thread类、实现Runnable接口、实现Callable接口通过FutureTask包装器来创建Thread线程、使用ExecutorService、Callable、Future实现有返回结果的多线程。
其中前两种方式线程执行完后都没有返回值,后两种是带返回值的。
1、继承Thread类创建线程
2、实现Runnable接口创建线程
1
2
3
4
5
6
7
8
|
public
class
MyThread
extends
OtherClass
implements
Runnable
{
public
void
run
(
)
{
System
.
out
.
println
(
"MyThread.run()"
)
;
}
}
MyThread
myThread
=
new
MyThread
(
)
;
Thread
thread
=
new
Thread
(
myThread
)
;
thread
.
start
(
)
;
|
3、实现Callable接口通过FutureTask包装器来创建Thread线程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
public
interface
Callable
<V>
{
V
call()
throws
Exception
;
}
public
class
SomeCallable
<V>
extends
OtherClass
implements
Callable
<V>
{
@Override
public
V
call
(
)
throws
Exception
{
// TODO Auto-generated method stub
return
null
;
}
}
Callable
<V>
oneCallable
=
new
SomeCallable
<V>
(
)
;
//由Callable<Integer>创建一个FutureTask<Integer>对象:
FutureTask
<V>
oneTask
=
new
FutureTask
<V>
(
oneCallable
)
;
//注释:FutureTask<Integer>是一个包装器,它通过接受Callable<Integer>来创建,它同时实现了Future和Runnable接口。
//由FutureTask<Integer>创建一个Thread对象:
Thread
oneThread
=
new
Thread
(
oneTask
)
;
oneThread
.
start
(
)
;
//至此,一个线程就创建完成了。
|
4、使用ExecutorService、Callable、Future实现有返回结果的线程
ExecutorService submit Callable后返回 Future 获取线程信息和结果
submit Runnable 则只能获取线程信息 无返回结果
Executors提供四种线程池,分别为:
newCachedThreadPool
创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool
创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool
创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor
创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行
进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程。(进程是资源分配的最小单位)
线程:同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换开销小。
线程和进程一样分为五个阶段:创建、就绪、运行、阻塞、终止。
start方法重复调用的话,会出现java.lang.IllegalThreadStateException异常。
实现Runnable接口比继承Thread类所具有的优势:
1):适合多个相同的程序代码的线程去处理同一个资源
2):可以避免java中的单继承的限制
3):增加程序的健壮性,代码可以被多个线程共享,代码和数据独立
4):线程池只能放入实现Runable或callable类线程,不能直接放入继承Thread的类
①sleep(long millis): 在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)
②join():指等待t线程终止。
③yield():暂停当前正在执行的线程对象,并执行其他线程。当前运行线程回到可运行状态
④setPriority(): 更改线程的优先级。
Thread.sleep()与Object.wait()二者都可以暂停当前线程,释放CPU控制权,主要的区别在于Object.wait()在释放CPU同时,释放了对象锁的控制。sleep() 不释放锁