Java 创建线程的方法
为了偷懒少敲几个字这里我写了一个Util类:
1 package test; 2 3 public class Util { 4 static void println() {System.out.println();} 5 static void println(Object obj) {System.out.println(obj);} 6 }
并且在之后的代码中都加入了:
1 package test; 2 import static test.Util.*;
1.实现Runnable接口
1 class simpleRunnable implements Runnable { 2 private int n = 3; 3 private static int count = 0; 4 protected final int id = count++; 5 6 public simpleRunnable() { 7 println("#" + id +" start"); 8 } 9 10 @Override 11 public void run() { 12 while(n-->0){ 13 println("#" +id +":" + n); 14 Thread.yield(); 15 } 16 println("#" + id +" end"); 17 } 18 } 19 20 public class test { 21 public static void main(String[] args) { 22 new Thread(new simpleRunnable()).start(); 23 } 24 }
还有一种自管理的Runnable:
1 class simpleRunnable2 implements Runnable { 2 private Thread t = new Thread(this); 3 private int n = 3; 4 private static int count = 0; 5 private final int id = count++; 6 public simpleRunnable2() {t.start();} 7 @Override 8 public void run() { 9 while(n-->0){ 10 println("#" +id +":" + n); 11 Thread.yield(); 12 } 13 println("#" + id +" end"); 14 } 15 } 16 17 public class test { 18 public static void main(String[] args) { 19 new simpleRunnable2(); 20 } 21 }
2.继承Thread类
1 class simpleThread extends Thread{ 2 private int n = 3; 3 private static int count = 0; 4 private final int id = count++; 5 6 public simpleThread() { 7 println("#" + id +" start"); 8 } 9 10 public void run() { 11 while(n-->0){ 12 println("#" +id +":" + n); 13 Thread.yield(); 14 } 15 println("#" + id +" end"); 16 } 17 } 18 19 public class test { 20 public static void main(String[] args) { 21 new simpleThread().start(); 22 } 23 }
3.内部类
3.1实现Runnable接口的内部类
1 class innerRunnable{ 2 private static int count = 0; 3 private Inner inner; 4 private class Inner implements Runnable { 5 private int n = 3; 6 private final int id = count++; 7 Thread t = new Thread(this); 8 public Inner() {t.start();} 9 @Override 10 public void run() { 11 while(n-->0){ 12 println("#" +id +":" + n); 13 Thread.yield(); 14 } 15 println("#" + id +" end"); 16 } 17 } 18 public innerRunnable() { 19 inner = new Inner(); 20 } 21 } 22 23 class innerRunnable2{ 24 private static int count = 0; 25 private Thread t; 26 public innerRunnable2() { 27 t = new Thread(new Runnable(){ 28 //实现Runnable接口的匿名内部类 29 private int n = 3; 30 private final int id = count++; 31 @Override 32 public void run() { 33 while(n-->0){ 34 println("ir2#" +id +":" + n); 35 Thread.yield(); 36 } 37 println("ir2#" + id +" end"); 38 } 39 }); 40 t.start(); 41 } 42 } 43 44 public class test { 45 public static void main(String[] args) { 46 new innerRunnable(); 47 new innerRunnable2(); 48 } 49 }
3.2继承Thread类的内部类
1 class innerThread { 2 private static int count = 0; 3 private Inner inner; 4 private class Inner extends Thread { 5 private int n = 3; 6 private final int id = count++; 7 public Inner(){ 8 super(); 9 start(); 10 } 11 public void run() { 12 while(n-->0){ 13 println("#" +id +":" + n); 14 Thread.yield(); 15 } 16 println("#" + id +" end"); 17 } 18 } 19 public innerThread(){ 20 inner = new Inner(); 21 } 22 } 23 24 public class test { 25 public static void main(String[] args) { 26 new innerThread(); 27 } 28 }
当然同样可以用匿名匿名内部类,和Runnable是类似的,就不放上来了。
3.3在方法中使用匿名内部类
1 class ThreadMethod { 2 private static int count = 0; 3 private Thread t; 4 public void runTask() { 5 if(t == null) { 6 t = new Thread(new Runnable(){ 7 private int n = 3; 8 private final int id = count++; 9 @Override 10 public void run() { 11 while(n-->0){ 12 println("ir2#" +id +":" + n); 13 Thread.yield(); 14 } 15 println("ir2#" + id +" end"); 16 } 17 }); 18 t.start(); 19 } 20 } 21 } 22 23 public class test { 24 public static void main(String[] args) { 25 new innerThread(); 26 } 27 }
4.使用Executor
首先import一些用的到的包:
1 import java.util.ArrayList; 2 import java.util.List; 3 import java.util.concurrent.Callable; 4 import java.util.concurrent.ExecutorService; 5 import java.util.concurrent.Executors; 6 import java.util.concurrent.Future; 7 import java.util.concurrent.TimeUnit;
4.1CachedThreadPool
public class test { public static void main(String[] args) { ExecutorService exec = Executors.newCachedThreadPool(); for(int i = 0; i < 5; i++) exec.execute(new simpleRunnable()); exec.shutdown(); } }
CachedThreadPool为每个任务创建一个线程。
4.2FixedThreadPool
1 public class test { 2 public static void main(String[] args) { 3 ExecutorService exec = Executors.newFixedThreadPool(3); 4 for(int i = 0; i < 5; i++) 5 exec.execute(new simpleRunnable()); 6 exec.shutdown(); 7 } 8 }
newFixedThreadPool()需要一个整型参数,记为n,并当参数n <=0 时抛出IllegalArgumentException;这个方法会一次行创建n个线程,并且在这n个线程都在有任务时将后来的线程加入一个队列中,所有的任务都被new并且被接收。
4.3SingleThreadExecutor
1 public class test { 2 public static void main(String[] args) { 3 ExecutorService exec = Executors.newSingleThreadExecutor(); 4 for(int i = 0; i < 5; i++) 5 exec.execute(new simpleRunnable()); 6 exec.execute(new simpleRunnable()); 7 exec.shutdown(); 8 } 9 }
SingleThreadExecutor就相当于线程数为1的FixedThreadPool。
4.4实现Callable接口
1 class simpleCallable implements Callable<Integer>{ 2 @Override 3 public Integer call() throws Exception { 4 return (int)(Math.random() * 10 + 1); 5 } 6 } 7 public class test { 8 public static void main(String[] args) { 9 ExecutorService exec = Executors.newCachedThreadPool(); 10 List<Future<Integer>> list = new ArrayList(); 11 for(int i = 0; i < 5; i++) 12 list.add(exec.submit(new simpleCallable())); 13 for(Future<Integer> f : list) 14 try { 15 println(f.get()); 16 } catch (InterruptedException e) { 17 e.printStackTrace(); 18 } catch (ExecutionException e) { 19 e.printStackTrace(); 20 } finally { 21 exec.shutdown(); 22 } 23 } 24 }
Runnable是执行工作的独立任务,但是它不会返回任何值,而实现Callable<V>可以在call()方法中产生类型为V的对象并返回其引用(我觉得这样说会比“返回类型为V的对象”更合适一些),并且必须使用ExecutorService。submit()来调用它;submit方法会产生Future对象并返回其引用,第一个for并不会被阻塞;可以用isDone()来查询任务是否完成,或者直接使用get()来取得结果,当get()时任务未完成则会阻塞get()。
4.5使用ThreadFactory
1 class simpleThreadFactory implements ThreadFactory { 2 @Override 3 public Thread newThread(Runnable r) { 4 Thread t = new Thread(r); 5 return t; 6 } 7 } 8 9 public class test { 10 public static void main(String[] args) { 11 ExecutorService exec = Executors.newCachedThreadPool(new simpleThreadFactory()); 12 exec.execute(new simpleRunnable()); 13 exec.shutdown(); 14 } 15 }