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 做处理

 

你可能感兴趣的:(java多线程)