码迷,mamicode.com
首页 > 编程语言 > 详细

Java多线程并发技术

时间:2015-09-07 20:56:55      阅读:182      评论:0      收藏:0      [点我收藏+]

标签:

Java多线程并发技术

参考文献:

http://blog.csdn.net/aboy123/article/details/38307539

http://blog.csdn.net/ghsau/article/category/1707779

http://www.iteye.com/topic/366591

JAVA多线程实现方式主要有三种:继承Thread类、实现Runnable接口、使用ExecutorService、Callable、Future实现有返回结果的多线程。其中前两种方式线程执行完后都没有返回值,只有最后一种是带返回值的。

1、 继承Thread类实现多线程

 

public class MyThread extends Thread {

  public void run() { //重写run方法

   System.out.println("MyThread.run()");

  }

}

 

//调用代码

MyThread myThread1 = new MyThread();

MyThread myThread2 = new MyThread();

myThread1.start(); // 启动线程

myThread2.start();

 

Thread本质上也是实现了Runnable接口的一个实例,它代表一个线程的实例,并且,启动线程的唯一方法就是通过Thread类的start()实例方法

2、 实现Runnable接口方式实现多线程

 

//如果自己的类已经extends另一个类,就无法直接extends Thread,此时,必须实现一个Runnable接口,如下:

public class MyThread extends OtherClass implements Runnable {

  public void run() {

   System.out.println("MyThread.run()");

  }

}

 

//为了启动MyThread,需要首先实例化一个Thread,并传入自己的MyThread实例:

MyThread myThread = new MyThread();

Thread thread = new Thread(myThread);

thread.start();

3、 使用ExecutorService、Callable、Future实现有返回结果的多线程

ExecutorService、Callable、Future这个对象实际上都是属于Executor框架中的功能类。可返回值的任务必须实现Callable接口,类似的,无返回值的任务必须Runnable接口。执行Callable任务后,可以获取一个Future的对象,在该对象上调用get就可以获取到Callable任务返回的Object了,再结合线程池接口ExecutorService就可以实现有返回结果的多线程了。

 

  1.      int taskSize = 5;     
  2.    ExecutorService pool = Executors.newFixedThreadPool(taskSize);  // 创建一个线程池  
  3.    // 创建多个有返回值的任务  
  4.    List<Future> list = new ArrayList<Future>();  
  5.    for (int i = 0; i < taskSize; i++) {  
  6.     Callable c = new MyCallable(i + " ");     
  7.     Future f = pool.submit(c);      // 执行任务并获取Future对象  
  8.     list.add(f);  
  9.    }     
  10.   pool.shutdown();    // 关闭线程池   
  11. for (Future f : list) {  
  12.  // 从Future对象上获取任务的返回值,并输出到控制台  
  13.  System.out.println(">>>" + f.get().toString());   //get()是阻塞调用
  14.  }   

  // 实现Callable接口

  1. class MyCallable implements Callable<Object> {  
  2. private String taskNum;    
  3. MyCallable(String taskNum) {  
  4.    this.taskNum = taskNum;  
  5. }    
  6. public Object call() throws Exception {     
  7.    Thread.sleep(1000);   
  8.    return taskNum + "任务返回运行结果,当前任务时间【" + time + "毫秒】";  
  9. }  

4、 Executors类说明:

参考文献:http://www.iteye.com/topic/366591

 

Executors类,提供了一系列工厂方法用于创建线程池,返回的线程池都实现了ExecutorService接口。

public static ExecutorService newFixedThreadPool(int nThreads)

创建固定数目线程的线程池。

public static ExecutorService newCachedThreadPool()

创建一个可缓存的线程池,调用execute 将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。

public static ExecutorService newSingleThreadExecutor()

创建一个单线程化的Executor。

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)

创建一个支持定时及周期性的任务执行的线程池,多数情况下可用来替代Timer类。

 

ExecutoreService提供了submit()方法,传递一个Callable,或Runnable,返回Future。如果Executor后台线程池还没有完成Callable的计算,这调用返回Future对象的get()方法,会阻塞直到计算完成。

5、 其他获得线程执行结果的方式:

http://blog.csdn.net/ghsau/article/details/7451464

基于FutureTask

在上述实现中,任务callable被提交后返回一个future用于获得执行结果;

FutureTask实现了两个接口,Runnable和Future,所以它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值;

 

  1. public class CallableAndFuture {  
  2.     public static void main(String[] args) {  
  3.         Callable<Integer> callable = new Callable<Integer>() {  
  4.             public Integer call() throws Exception {  
  5.                 return new Random().nextInt(100);  
  6.             }  
  7.         };  
  8.          FutureTask<Integer> future = new FutureTask<Integer>(callable);  
  9.       new Thread(future).start();  
  10.        try {  
  11.           Thread.sleep(5000);// 可能做一些事情  
  12.           System.out.println(future.get());  
  13.      } catch (InterruptedException e) {  
  14.           e.printStackTrace();  
  15.        } catch (ExecutionException e) {  
  16.           e.printStackTrace();  
  17.        }  
  18.    }  

     19.  }  

 

基于CompletionService的实现方式

 

  1.  public class CallableAndFuture {  
  2.     public static void main(String[] args) {  
  3.      ExecutorService threadPool = Executors.newCachedThreadPool();  
  4.         CompletionService<Integer> cs = new ExecutorCompletionService<Integer>(threadPool);  
  5.         for(int i = 1; i < 5; i++) {  
  6.             final int taskID = i;  
  7.             cs.submit(new Callable<Integer>() {  
  8.                 public Integer call() throws Exception {  
  9.                     return taskID;  
  10.              }  
  11.            });  
  12.          }  
  13.          // 可能做一些事情  
  14.          for(int i = 1; i < 5; i++) {  
  15.              try {  

        //take 每次获得一个执行完成的future,如果没有就阻塞,与其功能相同的非阻塞调用时poll

  1.                 System.out.println(cs.take().get());  
  2.            } catch (InterruptedException e) {  
  3.                  e.printStackTrace();  
  4.             } catch (ExecutionException e) {  
  5.                 e.printStackTrace();  
  6.              }  
  7.          }  
  8.       }  

       }  

 

6、 多线程相关函数:

参考文献:http://blog.csdn.net/ghsau/article/details/17560467

 

线程中断:http://blog.csdn.net/z69183787/article/details/25076033

void

interrupt()  //    中断线程。其实只是设置了中断标志位

static boolean

interrupted() //  测试调用该方法的当前线程是否已经中断。同时清除中断标志位

boolean

isInterrupted() // 测试this线程是否已经中断。不清除中断标志位

线程让步

static void

yield() //     暂停当前正在执行的线程对象,并执行其他线程

注意: 如果存在synchronized线程同步的话,线程让步不会释放锁(监视器对象)

线程休眠:

static void

sleep(long millis)//  在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)。

注意: 如果存在synchronized线程同步的话,线程休眠不会释放锁(监视器对象),但会释放cpu

 

线程合并:http://uule.iteye.com/blog/1101994

 void

join()          等待该线程终止。

 void

join(long millis)          等待该线程终止的时间最长为 millis 毫秒。

 void

join(long millis, int nanos) 等待该线程终止的时间最长为 millis 毫秒 + nanos 纳秒。

线程合并是优先执行调用该方法的线程,再执行当前线程。内部是用wait方法实现的

 

  1. public class JoinTest {  
  2.     public static void main(String[] args) throws InterruptedException {  
  3.         JoinThread t1 = new JoinThread("t1");  
  4.         JoinThread t2 = new JoinThread("t2");  
  5.         t1.start();   //启动线程
  6.         t2.start();  //启动线程
  7.         t1.join();   //等待该线程执行完毕
  8.         t2.join();  //
  9.         System.out.println("主线程开始执行!");  
  10.    }  

11. }  

      class JoinThread extends Thread {  

  1.      public JoinThread(String name) {  
  2.        super(name);  
  3.        }  
  4.       public void run() {  
  5.        for(int i = 1; i <= 10; i++)  
  6.             System.out.println(getName() + getId() + "执行了" + i + "次");  
  7.      }  

    } 

 

7、 线程同步之锁

 连接:http://blog.csdn.net/ghsau/article/details/7461369

 

Java多线程并发技术

标签:

原文地址:http://www.cnblogs.com/gaoyanqing/p/4789731.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!