java多线程一览

Posted 青瓷

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java多线程一览相关的知识,希望对你有一定的参考价值。

  • 线程概述:
    • 多线程的目的,不是提高程序的执行速度,而是提高程序的使用率(能抢到CPU的可能比较大). 因为线程是CPU调度的基本单位,所以,当一个程序的线程较多的时候就更容易抢到cpu的资源
    • 进程:
      • 运行中的程序,系统进行资源分配和调度的独立单位
      • 每个进程都有他自己的内存空间和系统资源
    • 线程:
      • 是进程中的单个顺序控制流,是一条执行路径,cpu调度的基本单位
      • 一个进程如果有多条执行路径,:多线程
      • 一个进程如果只有一条执行路径,:单线程
  • 线程生命周期:
    •  

  • java中线程概览: [ ps : 图来自郭朝:http://blog.csdn.net/smartbetter/article/details/51335165]
  • 继承Thread类 和 实现Runnable:
 1 /**
 2 *继承Thread类 和 实现Runnable:
 3 *        1.后者解决了java单继承的局限性
 4         2.后者更适合多个相同的程序代码处理同一个资源的情况,将数据与代码有效分离,体现了java面向对象的思维
 5 *
 6 *有人说:
 7 *    前者是多个线程各自执行各自的任务,
 8 *    后者是多个线程处理相同的任务
 9 *
10 *一般用后者的人居多,因为更灵活
11 */
12 
13 // 继承Thread类
14 class MyThread extends Thread{
15     private static Object shareData; // 实现数据共享
16     @Overwrite
17     public void run(){
18         System.out.println("当前线程是"+Thread.currentThread.getName());
19     }
20 }
21 // 创建线程
22 class Main{
23     public static void main(String[] args) {
24         Thread thread=new MyThread();
25         Thread thread2=new MyThread();
26         thread.start(); // 线程开启
27         thread2.start(); // 线程开启
28     }
29 }
View Code
  • 实现Runnable创建线程类:

  

 1 // 实现Runnable创建线程类
 2 class MyRunnable implements Runnable{
 3     private Object shareData; // 实现数据共享
 4     public void run(){
 5         System.out.println("当前线程是"+Thread.currentThread.getName());
 6     }
 7 }
 8 //创建线程
 9 class Main{
10     public static void main(String[] args) {
11         // 两个线程将共享shareData共享数据
12         Runnable runa=new MyRunnable();
13         Thread thread=new MyThread(runa);
14         Thread thread2=new MyThread(runa);
15         thread.start(); // 线程开启
16         thread2.start(); // 线程开启
17     }
18 }
View Code
  • 使用Callable 和 Future接口:

  

 1 /**
 2  * 该代码来源: @蛊惑Into
 3  * Callable 和 Future接口
 4  * Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其它线程执行的任务。
 5  * Callable和Runnable有几点不同:
 6  * (1)Callable规定的方法是call(),而Runnable规定的方法是run().
 7  * (2)Callable的任务执行后可返回值,而Runnable的任务是不能返回值的。
 8  * (3)call()方法可抛出异常,而run()方法是不能抛出异常的。
 9  * (4)运行Callable任务可拿到一个Future对象,
10  * Future 表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。
11  * 通过Future对象可了解任务执行情况,可取消任务的执行,还可获取任务执行的结果。
12  */
13 public class CallableAndFuture {
14 
15     public static class  MyCallable  implements Callable{
16           private int flag = 0; 
17           public MyCallable(int flag){
18                   this.flag = flag;
19           }
20           public String call() throws Exception{
21             if (this.flag == 0){  
22                       return "flag = 0";
23             } 
24             if (this.flag == 1){   
25                 try {
26                     while (true) {
27                             System.out.println("looping.");
28                             Thread.sleep(2000);
29                     }
30                 } catch (InterruptedException e) {
31                               System.out.println("Interrupted");
32                 }
33                 return "false";
34             } else {   
35                        throw new Exception("Bad flag value!");
36             }
37         }
38     }
39 
40     public static void main(String[] args) {
41 
42        // 定义3个Callable类型的任务
43         MyCallable task1 = new MyCallable(0);
44         MyCallable task2 = new MyCallable(1);
45         MyCallable task3 = new MyCallable(2);      
46 
47        // 创建一个执行任务的服务
48        ExecutorService es = Executors.newFixedThreadPool(3);
49         try {
50            // 提交并执行任务,任务启动时返回了一个Future对象,
51 
52             // 如果想得到任务执行的结果或者是异常可对这个Future对象进行操作
53             Future future1 = es.submit(task1);
54            // 获得第一个任务的结果,如果调用get方法,当前线程会等待任务执行完毕后才往下执行
55             System.out.println("task1: " + future1.get());
56         
57 
58             Future future2 = es.submit(task2);
59            // 等待5秒后,再停止第二个任务。因为第二个任务进行的是无限循环
60             Thread.sleep(5000);
61             System.out.println("task2 cancel: " + future2.cancel(true));
62 
63             
64            // 获取第三个任务的输出,因为执行第三个任务会引起异常
65             // 所以下面的语句将引起异常的抛出
66             Future future3 = es.submit(task3);
67             System.out.println("task3: " + future3.get());
68         } catch (Exception e){
69             System.out.println(e.toString());
70         }
71 
72        // 停止任务执行服务
73         es.shutdownNow();
74 
75     }
76 
77 }
View Code

 

  • 线程控制:

  

 1 // 线程控制
 2 
 3 join()线程---必须等线程th执行完成后才能继续向下执行
 4 ...
 5 th.start();
 6 th.join();
 7 ... 
 8 
 9 yield()礼让---注意和线程通信中wait()区分,yield将线程放到就绪队列,而wait将其放到阻塞队列
10 ...th.doSomething...
11 th.yield();
12 ...th.doSomethingElse...
13 
14 sleep()睡眠---线程睡眠,将进入阻塞队列
15 ...doSomething...
16 Thread.sleep(1000);
17 ...continueDoSomething...
18 
19 setDaemon()后台线程---将线程设置为后台线程,将在前台线程都死亡后自动死亡
20 ....
21 th.setDaemon(true);
22 ....
23 
24 setPrority()优先级---设置优先级
25 ...
26 th.setPrority(5);
27 th.start();
28 ...
View Code
  • 线程同步的3种实现:

  

  1 /* 线程同步的3种实现:
  2 *    1.同步代码块:锁对象可以是任意对象
  3                     synchronized(obj){同步代码块}
  4 *    2.同步方法:
  5             2.1 普通同步方法,锁对象是this
  6                     public synchronized void fun(){...}
  7             2.2 静态同步方法,锁对象是.class字节码对象
  8                     public static synchronized void fun(){...}
  9     3.同步锁:javaAPI提供了多种锁,如读写锁等,以及一些工具类的锁(同时具有同步和通讯特点)
 10             private Lock lock=new ReentrantLock();
 11             ...
 12             lock.lock();
 13             ...doSomething...
 14             lock.unLock();
 15 *
 16 *    
 17 *以下着重介绍几种工具类的锁使用:
 18         Samaphore
 19         CyclicBarrier
 20         CountDownLatch
 21 */
 22 /**
 23  * 线程互斥与通信:
 24  *         线程通讯之传统线程通讯: Semaphore信号灯工具
 25  *         传统的互斥,是由线程本身来控制锁的占有和释放,这就导致必须当前线程完成,或是主动让出锁,下一个线程才有机会,
 26  *         而semaphore工具, 提供相当于专门的锁的管理方全权控制索,任何线程的请求都通过管理方的许可,这样就解放了锁的控制权,让多个线程共享锁
 27  *
 28  *共有3盏灯,一次来了10个人,只用其中的3个人能够拿到等,当有灯还回的时候,等候队列的人才有机会拿到灯
 29  *可用于死锁恢复的一些场景
 30  *  
 31  * @throws Exception
 32  * @author ware E-mail:
 33  * @version create time: 20172017年3月1日下午11:35:41
 34  */
 35 public class ThreadCommunication3 {
 36     
 37     public static void main(String[] args) {
 38         final Semaphore sp=new Semaphore(3, true);
 39         
 40         ExecutorService pool = Executors.newCachedThreadPool();
 41         
 42         for (int i = 0; i < 10; i++) {
 43             Runnable task=new Runnable() {
 44                 @Override
 45                 public void run() {
 46                     try {
 47                         sp.acquire(); // 请求锁
 48                     } catch (InterruptedException e) {
 49                         e.printStackTrace();
 50                     }
 51                     System.out.println("线程"+Thread.currentThread().getName()+"已经进入---可用数"+(3-sp.availablePermits()));
 52                     
 53                     try {
 54                         Thread.sleep(1000);
 55                     } catch (InterruptedException e) {
 56                         e.printStackTrace();
 57                     }
 58                     
 59                     System.out.println("线程"+Thread.currentThread().getName()+"准备离开");
 60                     
 61                     sp.release(); //释放锁
 62                 }
 63             };
 64             
 65             pool.submit(task);
 66         }
 67         
 68     }
 69     
 70     
 71 }
 72 
 73 /**
 74  * 线程互斥与通信:
 75  *         线程通讯之传统线程通讯: CyclicBarrier工具
 76  *         所有规定的线程必须都在完成某一项工作之后才能继续下一项工作
 77  * 
 78  * 如: 班级郊游,只有所有的人都到了集合点(工作1)才能出发(工作2)
 79  *  
 80  * @throws Exception
 81  * @author ware E-mail:
 82  * @version create time: 20172017年3月1日下午11:35:41                 
 83  */
 84 public class ThreadCommunication4 {
 85     
 86     public static void main(String[] args) {
 87         final CyclicBarrier cb=new CyclicBarrier(4); // 约定有多少个人
 88         
 89         ExecutorService pool = Executors.newCachedThreadPool();
 90         
 91         for (int i = 0; i < 4; i++) {
 92             Runnable task=new Runnable() {
 93                 @Override
 94                 public void run() {
 95                     
 96                     try {
 97                         // 第一阶段工作
 98                         Thread.sleep((long) (Math.random()*1000));
 99                         System.out.println(Thread.currentThread().getName()+"到达集合点,当前共有"+cb.getNumberWaiting()+"人在等待");
100                         cb.await();
101                         
102                         // 第二阶段工作
103                         Thread.sleep((long) (Math.random()*1000));
104                         System.out.println(Thread.currentThread().getName()+"出发中"+cb.getNumberWaiting()+"人出发中");
105                         cb.await();
106                         
107                         // 第三阶段工作
108                         Thread.sleep((long) (Math.random()*1000));
109                         System.out.println(Thread.currentThread().getName()+"到达景点"+cb.getNumberWaiting()+"人到达景点");
110                         cb.await();
111                         
112                     } catch (Exception e) {
113                         e.printStackTrace();
114                     }
115                     
116                 }
117                     
118             };
119             
120             pool.submit(task);
121         }
122         
123     }
124 
125 }
126 
127 /**
128  * 线程互斥与通信:
129  *         线程通讯之传统线程通讯: CountDownLatch工具
130  *         如同一个倒计时器,当countDown()到0的时候,所有等该"计时器"的线程都会受到消息
131  * 
132  * 如: 所有的运动员都在等裁判的命令,裁判一声令下,所有的运动员收到消息开始跑,裁判等到所有的人都跑到终点了才宣布结构
133  *  
134  * @throws Exception
135  * @author ware E-mail:
136  * @version create time: 20172017年3月1日下午11:35:41                 
137  */
138 public class ThreadCommunication6 {
139     
140     public static void main(String[] args) {
141         final CountDownLatch cdOrder=new CountDownLatch(1); // 裁判命令
142         final CountDownLatch cdAnswer=new CountDownLatch(4); // 运动员的消息状态
143         
144         ExecutorService pool = Executors.newCachedThreadPool();
145         
146         // 4个运动员
147         for (int i = 0; i < 4; i++) {
148             Runnable task=new Runnable() {
149                 @Override
150                 public void run() {
151                     
152                     try {
153                         System.out.println(Thread.currentThread().getName()+"---已经准备好了,等待命令");
154                         
155                         cdOrder.await(); // 等命令
156                         
157                         System.out.println("等到命令并开跑");
158                         Thread.sleep((long) (Math.random()*1000));
159                         System.out.println(Thread.currentThread().getName()+"跑完全程了");
160                         
161                         cdAnswer.countDown();
162                         
163                     } catch (Exception e) {
164                         e.printStackTrace();
165                     }
166                     
167                 }
168                     
169             };
170             
171             pool.submit(task);
172         }
173         
174         
175         // 1个裁判
176         Runnable coach=new Runnable() {
177             @Override
178             public Java多线程——Lock&Condition

Java多线程与并发库高级应用-工具类介绍

Java多线程与并发库高级应用-工具类介绍

多线程 Thread 线程同步 synchronized

Java多线程具体解释

自己开发的在线视频下载工具,基于Java多线程