Java多线程
1、创建多线程,通过继承Thread类或者实现Runnable接口
View Code
1
package multithread;
2
public
class MultiThread {
3
public
static
void main(String[] args) {
4
int i=5;
5
for(
int j=0;j<i;j++){
6
new Thread(
new RunabledImp()).start();
7 }
8 System.out.println("**********************");
9
for(
int j=0;j<i;j++){
10
new RunabledImp().run();
11 }
12
new NewThread().start();
13 }
14
static
class NewThread
extends Thread{
15 @Override
16
public
void run(){
17 setName("new thread");
18 System.out.println("New thread");
19 }
20 }
21
static
class RunabledImp
implements Runnable{
22
private
int count=10;
23
private
static
int countDown=0;
24
private
final
int threadCount=countDown++;
25
public RunabledImp(
int index){
26
//
threadCount=index;
27
}
28
public RunabledImp(){
29 }
30
private String status(){
31
return "#"+threadCount+" "+count+"thread";
32 }
33 @Override
34
public
void run() {
35
while(count-->0){
36 System.out.println(status());
37 }
38 System.out.println("count:"+count);
39 }
40 }
41 }
运行后:。。。
#1 3thread
#1 2thread
#1 1thread
#1 0thread
New thread
2、使用
Executors 创建线程管理
Executors 可以创建
newCachedThreadPool ,
newFixedThreadPool ,
newSingleThreadExecutor ,
其中CachedThreadPool创建新的线程池,并在可以使用时重用他们,最大线程数Integer.MAX_VALUE
FixedThreadPool 创建固定大小的线程池,以共享的无界队列方式来运行这些线程
newSingleThreadExecutor :创建一个使用单个 worker 线程的 Executor,以无界队列方式来运行该线程。
newScheduledThreadPool :创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。
推荐使用这些管理线程,不用自己在创建threadkpool,以上方法也可以使用自己的
ThreadFactory
threadFactory去创建Thread,可以修改名称、设置优先级等
View Code
1
package multithread;
2
3
import java.util.concurrent.ExecutorService;
4
import java.util.concurrent.Executors;
5
import java.util.concurrent.ScheduledExecutorService;
6
import java.util.concurrent.ScheduledFuture;
7
import java.util.concurrent.TimeUnit;
8
9
public
class ExecutorThread {
10
11
public
static
void main(String[] args) {
12 ExecutorService exec=Executors.newCachedThreadPool();
13
for(
int i=0;i<5;i++){
14 exec.execute(
new MultiThread.RunabledImp());
15 }
16 System.out.println("*******************");
17 ExecutorService fixExec=Executors.newFixedThreadPool(3);
18
for(
int i=0;i<5;i++){
19 fixExec.execute(
new MultiThread.RunabledImp());
20 }
21 System.out.println("*******************");
22 ExecutorService singleExec=Executors.newSingleThreadExecutor();
23
for(
int i=0;i<5;i++){
24 singleExec.execute(
new MultiThread.RunabledImp());
25 }
26 ScheduledExecutorService scheduledExec=Executors.newScheduledThreadPool(5);
27
28
for(
int i=0;i<5;i++){
29
//
scheduledExec.execute(new MultiThread.RunabledImp());
30
final ScheduledFuture<?> beeperHandle =
31 scheduledExec.scheduleAtFixedRate(
new MultiThread.RunabledImp(), 1, 5, TimeUnit.SECONDS);
32
/*
33
scheduledExec.schedule(new Runnable() {
34
public void run() { beeperHandle.cancel(true); }
35
}, 20, TimeUnit.SECONDS);
36
*/
37 }
38
39 exec.shutdown();
40 fixExec.shutdown();
41 singleExec.shutdown();
42 ExecutorService newExec= Executors.newCachedThreadPool(Executors.defaultThreadFactory());
43 Thread.setDefaultUncaughtExceptionHandler(
new ExecutorThread().
new UnCaughtHandlerException());
44 newExec.execute(
new Runnable() {
45
46 @Override
47
public
void run() {
48
throw
new RuntimeException("test exception");
49
50 }
51 });
52 Thread t=
new Thread(){
53 {setName("new Thread Exception Test");};
54 @Override
55
public
void run(){
56
throw
new RuntimeException("test exception");
57 }
58 };
59 t.setUncaughtExceptionHandler(
new ExecutorThread().
new UnCaughtHandlerException2());
60 t.start();
61
62 }
63
64
class UnCaughtHandlerException2
implements Thread.UncaughtExceptionHandler{
65 @Override
66
public
void uncaughtException(Thread t, Throwable e) {
67 System.out.println("UnCaughtHandlerException2"+t.getName()+e.getMessage());
68 }
69 }
70
class UnCaughtHandlerException
implements Thread.UncaughtExceptionHandler{
71 @Override
72
public
void uncaughtException(Thread t, Throwable e) {
73 System.out.println(t.getName()+e.getMessage());
74 }
75 }
76 }
由于不能在线程中捕获线程中逃逸的异常,可以继承Thread.UncaughtExceptionHandler,创建自己的异常类UnCaughtHandlerException ,内部类,作为Thread错误时用于处理错误,也可以设置单独的异常处理类
Thread t=new Thread();
t.setUncaughtExceptionHandler(new ExecutorThread().new UnCaughtHandlerException2());
或者
Thread.setDefaultUncaughtExceptionHandler(new ExecutorThread().new UnCaughtHandlerException());
3、后台线程:
Daemon
View Code
1
package multithread;
2
public
class DaemonThread
implements Runnable {
3
public
void run() {
4
while (
true) {
5 System.out.println(Thread.currentThread().getName() + "在运行");
6 }
7 }
8
public
static
void main(String[] args) {
9 DaemonThread he =
new DaemonThread();
10 Thread demo =
new Thread(he, "线程");
11
//
虽然是死循环,但是程序依然会执行完并停止
12
demo.setDaemon(
true);
13 demo.start();
14 }
15 }
当所有的非后台线程都结束后,后台线程也将停止
4、Join
调用thread的join()方法,意味着等待该线程终止,也就是说某个线程在另一个线程t上调用t.join(),此线程将被挂起,直到目标线程结束才恢复。join()方法可以设置超时,当超时后肯定返回。join()方法可以被中断
View Code
1
package multithread;
2
public
class JoinThread {
3
class Sleeper
extends Thread{
4
private
int duration;
5
public Sleeper(String name,
int sleepTime){
6
super(name);
7
this.duration=sleepTime;
8 start();
9 }
10 @Override
11
public
void run(){
12
try{
13 sleep(duration);
14 }
catch (Exception e) {
15 System.out.println(getName()+" was interrupted");
16 }
17 System.out.println(getName()+" has awakened");
18 }
19 }
20
class Joiner
extends Thread{
21
private Sleeper sleeper;
22
public Joiner(String name,Sleeper sleeper){
23
super(name);
24
this.sleeper=sleeper;
25 start();
26 }
27 @Override
28
public
void run(){
29
try {
30
//
Join可设置超时
31
sleeper.join();
32
//
sleep(5000);
33
}
catch (InterruptedException e) {
34 System.out.println(getName()+" interrupt");
35 }
36 System.out.println(getName()+" join completed");
37 }
38 }
39
public
static
void main(String[] args) {
40 JoinThread jt=
new JoinThread();
41 Sleeper s1=jt.
new Sleeper("s1", 5000);
42 Sleeper s2=jt.
new Sleeper("s2", 5000);
43 Joiner j1=jt.
new Joiner("j1", s1);
44 Joiner j2=jt.
new Joiner("j2", s2);
45 }
46 }
运行结果:
s1 has awakened
j1 join completed
s2 has awakened
j2 join completed
5、带有返回结果
线程在执行时没有返回结果,如果想要有返回结果,应该继承Callable接口,并实现call方法。通过ExecutorService.submit提交,并get()获取返回值,其中get()方法会阻塞直到有结果,可以设置超时,例如:
List<Future<String>> result=new ArrayList<Future<String>>();
for(int i=0;i<10;i++){
result.add(exec.submit(new TaskWithResult<String>(i,s)));
}
for(Future<String> fs:result){
try {
System.out.println(fs.get());
完整代码:
View Code
1
package multithread;
2
3
import java.util.ArrayList;
4
import java.util.List;
5
import java.util.concurrent.Callable;
6
import java.util.concurrent.ExecutionException;
7
import java.util.concurrent.ExecutorService;
8
import java.util.concurrent.Executors;
9
import java.util.concurrent.Future;
10
import java.util.concurrent.TimeUnit;
11
import java.util.concurrent.TimeoutException;
12
13
public
class CallableDemo {
14
static
class TaskWithResult<T>
implements Callable<T>{
15
private T t;
16
public TaskWithResult(
int id,T t){
17
this.t=t;
18 }
19 @Override
20
public T call()
throws Exception {
21 Thread.sleep(2000);
22
return
this.t;
23 }
24
25 }
26
static
class Person{
27 String firstName;
28 String secName;
29
private Person(String firstName,String secName){
30
this.firstName=firstName;
31
this.secName=secName;
32 }
33
public Person createPerson(String firstName,String secondName){
34
return
new Person(firstName,secondName);
35 }
36
public String toString(){
37
return
this.firstName+secName;
38 }
39 }
40
public
static
void main(String[] args) {
41 ExecutorService exec=Executors.newCachedThreadPool();
42 List<Future<String>> result=
new ArrayList<Future<String>>();
43 String s="test";
44
for(
int i=0;i<10;i++){
45 result.add(exec.submit(
new TaskWithResult<String>(i,s)));
46 }
47
for(Future<String> fs:result){
48
try {
49 System.out.println(fs.get());
50
//
System.out.println(fs.get(1000,TimeUnit.MILLISECONDS).toString());
51
}
catch (InterruptedException e) {
52 e.printStackTrace();
53 }
catch (ExecutionException e) {
54 e.printStackTrace();
55 }
finally{
56
//
exec.shutdown();
57
}
58 }
59
60
//
Person test
61
List<Future<Person>> persons=
new ArrayList<Future<Person>>();
62 List<Person> personsList=
new ArrayList<Person>();
63 Person a=
new Person("a", "a");
64 Person b=
new Person("b", "b");
65 Person c=
new Person("c", "c");
66 Person d=
new Person("d", "d");
67 personsList.add(a);
68 personsList.add(b);
69 personsList.add(c);
70 personsList.add(d);
71
for(
int i=0;i<4;i++){
72 persons.add(exec.submit(
new TaskWithResult<Person>(i,personsList.get(i))));
73 }
74
for(Future<Person> fs:persons){
75
try {
76 System.out.println(fs.get(1000,TimeUnit.MILLISECONDS).toString());
77 }
catch (InterruptedException e) {
78 e.printStackTrace();
79 }
catch (ExecutionException e) {
80 e.printStackTrace();
81 }
catch (TimeoutException e) {
82 e.printStackTrace();
83 }
finally{
84 exec.shutdown();
85 }
86 }
87 }
88 }
结果:
test
test
test
test
test
test
test
test
test
test
java.util.concurrent.TimeoutException
at java.util.concurrent.FutureTask$Sync.innerGet(Unknown Source)
at java.util.concurrent.FutureTask.get(Unknown Source)
at multithread.CallableDemo.main(CallableDemo.java:76)
bb
cc
dd
如果设置超时,将TimeoutException 做处理