JAVA多线程--1

 

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 可以创建newCachedThreadPoolnewFixedThreadPoolnewSingleThreadExecutor
其中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 做处理

 

posted @ 2012-06-23 17:43  wasp  阅读(395)  评论(0编辑  收藏  举报