标签:
1.通过继承thread类,覆写run方法来实现多线程。
1 public class Mytest { 2 public static void main(String[] args) { 3 Thread myThread1 = new MyThread1(); 4 Thread myThread2 = new MyThread1(); 5 //调用start方法 6 myThread1.start(); 7 myThread2.start(); 8 //调用run方法 9 //myThread1.run(); 10 //myThread2.run(); 11 } 12 } 13 14 class MyThread1 extends Thread { 15 public void run(){ 16 for(int i=0; i<10; i++){ 17 System.out.println(i); 18 try { 19 Thread.sleep(10); 20 } catch (InterruptedException e) { 21 // TODO Auto-generated catch block 22 e.printStackTrace(); 23 } 24 } 25 26 } 27 }
此时应该调用start()方法来启动一个线程,这样该线程就处于就绪状态,thread类会调用run()方法来执行该线程,这样上面的代码就会交替执行输出。
如果直接使用run()方法,它仅仅只是调用了一个方法,这个方法只是在主线程依次执行,这样上面的代码就会依次输出。
2.通过实现Runnable接口来实现多线程。(其实Thread类也是实现了Runable接口,public class Thread extends Object implements Runnable)
1 public class Mytest2 { 2 public static void main(String[] args) { 3 MyThread2 mythread = new MyThread2(); 4 Thread thread1 = new Thread(mythread); 5 Thread thread2 = new Thread(mythread); 6 //执行start方法 7 thread1.start(); 8 thread2.start(); 9 //执行run方法 10 //thread1.run(); 11 //thread2.run(); 12 } 13 14 } 15 16 class MyThread2 implements Runnable { 17 @Override 18 public void run() { 19 for(int i=0; i<10; i++){ 20 System.out.println(i); 21 try { 22 Thread.sleep(10); 23 } catch (InterruptedException e) { 24 // TODO Auto-generated catch block 25 e.printStackTrace(); 26 } 27 } 28 29 } 30 31 }
因为实现Runable子类是没有start()方法的,所以通过Thread类的public Thread(Runnable target)构造方法来实现。
在实际的项目中,因为java只能继承单一类,可实现多接口,所以通常用继承Runable接口来实现多线程。
在继承Thread类和实现Runable接口还有一个重要的区别,后者能很方便的实现资源的共享。后者可以通过
MyThread2 mythread = new MyThread2();
Thread thread1 = new Thread(mythread);
Thread thread2 = new Thread(mythread);
让thread1和thread2共享资源,因为他们传的是同一个mythread。
3.使用Executor框架来实现多线程。
为什么要用到Executor框架呢?
Executor框架可以很方便的实现有返回结果的多线程,以上的两种方法都是没有返回值的。
1 public class Mytest3 { 2 public static void main(String[] args) { 3 //设定线程的数量 4 int threadSize = Runtime.getRuntime().availableProcessors(); 5 //通过Executors获取一个线程数量固定的线程池 6 ExecutorService threadPool = Executors.newFixedThreadPool(threadSize); 7 //用来存放返回结果 8 List<Future> fList = new ArrayList<Future>(); 9 //提交任务到线程池 10 for(int i=0; i<10; i++){ 11 Future f = threadPool.submit(new CallFunction(i, "我的线程" + i)); 12 fList.add(f); 13 } 14 threadPool.shutdown(); 15 //获取返回的结果 16 for(Future f : fList){ 17 try { 18 System.out.println(f.get().toString()); 19 } catch (InterruptedException e) { 20 // TODO Auto-generated catch block 21 e.printStackTrace(); 22 } catch (ExecutionException e) { 23 // TODO Auto-generated catch block 24 e.printStackTrace(); 25 } 26 } 27 } 28 29 } 30 class CallFunction implements Callable<Object> { 31 //线程id 32 private int taskId; 33 //线程内容 34 private String taskContent; 35 36 CallFunction(int taskId, String taskContent){ 37 this.taskId = taskId; 38 this.taskContent = taskContent; 39 } 40 41 //每个线程调用的方法 42 @Override 43 public Object call() throws Exception { 44 String result = taskId + ":" + taskContent; 45 return result; 46 } 47 48 }
以上代码主要设计到了ExecutorService、CallFunction、Future。
ExecutorService主要是通过Executors.newFixedThreadPool获取一个固定的线程池
CallFunction是实现了Callable接口,与Runable接口不同的是,Callable能返回值,而Runable不能返回值
Future是用于接收返回值,在submit的时候它是多线程并行的提交,而在使用Future的get方法的时候,它会串行的等待线程执行完毕直到返回结果。
标签:
原文地址:http://www.cnblogs.com/fakers/p/4845363.html