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 }

  • 实现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 }

  • 使用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 }

  • 线程控制:

  

 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 ...

  • 线程同步的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 void run() {
179                 try {
180                     System.out.println(Thread.currentThread().getName()+"准备开炮.....碰...");
181                     cdOrder.countDown();
182                     System.out.println(Thread.currentThread().getName()+"命令已发出,等待结果...");
183
184                     cdAnswer.await();
185                     System.out.println(Thread.currentThread().getName()+"比赛结束,成绩出来了");
186
187                 } catch (InterruptedException e) {
188                     e.printStackTrace();
189                 }
190
191             }
192         };
193         pool.submit(coach);
194
195
196     }
197
198
199 }

  • 线程通讯:

  

  1 /*
  2 *3种线程通讯:
  3     1. 传统线程通讯--wait(),notify();
  4     2. Condition线程通讯;
  5     2. BlockingQueue阻塞队列
  6 *
  7 */
  8 /**
  9  * 线程互斥与通信:
 10  *         线程通讯之传统线程通讯: wait(),notify(),notifyAll()(必须配合synchronized关键字)
 11  *
 12  *父线程执行10次,
 13  *子线程执行50次
 14  * @author ware E-mail:
 15  * @version create time: 20172017年3月1日下午11:35:41
 16  */
 17 public class ThreadCommunication {
 18     private static boolean isSub=false;
 19
 20     public synchronized void doit(){
 21         while(true){
 22             while(isSub){
 23                 try {
 24                     this.wait();
 25                 } catch (InterruptedException e) {
 26                     e.printStackTrace();
 27                 }
 28             }
 29             try {
 30                 Thread.sleep(1000);
 31             } catch (InterruptedException e) {
 32                 e.printStackTrace();
 33             }
 34             for (int i = 0; i < 10; i++) {
 35                 System.out.println("main"+"----------"+i);
 36             }
 37             isSub=true;
 38             this.notify();
 39         }
 40
 41     }
 42     public synchronized void doit2(){
 43         while(true){
 44             while(!isSub){
 45                 try {
 46                     this.wait();
 47                 } catch (InterruptedException e) {
 48                     e.printStackTrace();
 49                 }
 50             }
 51             try {
 52                 Thread.sleep(1000);
 53             } catch (InterruptedException e) {
 54                 // TODO Auto-generated catch block
 55                 e.printStackTrace();
 56             }
 57             for (int i = 0; i < 50; i++) {
 58                 System.out.println("sub"+"----------"+i);
 59             }
 60             isSub=false;
 61             this.notify();
 62         }
 63     }
 64
 65     public static void main(String[] args) {
 66         ThreadCommunication tc=new ThreadCommunication();
 67
 68         // 父线程
 69         Thread fatherTh=new Thread(){
 70                 @Override
 71                 public void run() {
 72                     tc.doit();
 73                 }
 74             };
 75
 76             // 子线程
 77         Thread sonTh=new Thread(){
 78                 @Override
 79                 public void run() {
 80                     tc.doit2();
 81                 }
 82             };
 83
 84         fatherTh.start();
 85         sonTh.start();
 86     }
 87 }
 88
 89 /**
 90  * 线程互斥与通信:
 91  *         线程通讯之传统线程通讯: Condition(必须配合Lock使用)
 92
 93  * 是对阻塞队列的实现: ArrayBlockQueue
 94  * @throws Exception
 95  * @author ware E-mail:
 96  * @version create time: 20172017年3月1日下午11:35:41
 97  */
 98 public class ThreadCommunication2 {
 99
100     private static final Lock lock=new ReentrantLock();
101     private static final Condition notFull=lock.newCondition();
102     private static final Condition notEmpty=lock.newCondition();
103
104     private Object resources[];
105
106     int putIndex; // 下一个可取的资源索引
107     int takeIndex; // 下一个可以存放资源的索引
108     int count; // 当前总资源数
109
110     public ThreadCommunication2(int resourceLimit) {
111         resources=new Object[resourceLimit];
112         this.putIndex=0;
113         this.takeIndex=0;
114         this.count=0;
115     }
116
117     public void put(Object taskResource){
118         lock.lock();
119         try {
120             while(count==resources.length){
121                 notFull.await();
122             }
123             System.out.println("-----------------put");
124             resources[putIndex]=taskResource;
125             putIndex=(putIndex%resources.length);
126             count++;
127             notEmpty.signalAll();
128         } catch (Exception e) {
129             e.printStackTrace();
130         }finally{
131             lock.unlock();
132         }
133     }
134
135     public Object take(){
136         Object result=null;
137         lock.lock();
138         try {
139             while(count==0){
140                 notEmpty.await();
141             }
142             System.out.println("----------------take");
143             result=resources[takeIndex];
144             takeIndex=(takeIndex+1)%resources.length;
145             count--;
146
147             notFull.signalAll();
148         } catch (Exception e) {
149             e.printStackTrace();
150         }finally{
151             lock.unlock();
152         }
153
154         return result;
155     }
156
157
158     public static void main(String[] args) {
159         ThreadCommunication2 tc=new ThreadCommunication2(7); // 资源队列的长度为7
160
161         // 开10个放线程
162         for (int i = 0; i < 10; i++) {
163             new Thread(new Runnable() {
164                 @Override
165                 public void run() {
166                     tc.put(Thread.currentThread().getName());
167                 }
168             }).start();
169         }
170
171         // 开10个拿线程
172         for (int i = 0; i < 10; i++) {
173             new Thread(new Runnable() {
174                 @Override
175                 public void run() {
176                     System.out.println(tc.take());
177                 }
178             }).start();
179         }
180     }
181
182 }
183
184
185 /**
186 *BlockingQueue阻塞队列
187 *放线程在队列满的时候直接放弃,通知拿线程,然后进入阻塞队列,
188 *拿线程在队列空的时候直接放弃,通知放线程,然后进入阻塞队列,
189 */
190 public class DequeueTest {
191
192     private final static BlockingQueue<Object> queue=new ArrayBlockingQueue<>(5);
193
194     public static void main(String[] args) throws InterruptedException {
195
196         // 开10个放线程
197         for (int i = 0; i < 10; i++) {
198             new Thread(new Runnable() {
199                 @Override
200                 public void run() {
201                     queue.add(Thread.currentThread().getName());
202                 }
203             }).start();
204         }
205
206         // 开10个拿线程
207         for (int i = 0; i < 10; i++) {
208             new Thread(new Runnable() {
209                 @Override
210                 public void run() {
211                     System.out.println(queue.remove());
212                 }
213             }).start();
214         }
215
216     }
217
218 }

  • 线程数据共享:

  

 1 /* 线程数据共享:
 2  *        1.多个线程间共享同一个数据:
 3             1.1.多个线程的执行代码相同---多个线程共用一个Runnable的实例, 那么Runnable中的类成员将被共享;
 4  *             1.2.多个线程的执行代码不同---为多个Runnable对象传入同一个实体对象
 5  *             1.3.多个线程的执行代码不同---将多个Runnable设置为内部类,将共享实体设置为外部类成员变量
 6  *        2.一个线程的多个代码块共享一个数据:
 7  *            2.1 将 (线程,数据对象) 放到一个map中,
 8  *            2.2 一般使用java类库提供的ThreadLocal,实现原理同上,但是更优雅,而且会在线程结束后自动清理
 9  *
10  * 线程间的数据共享比较简单,这里着重介绍线程内的数据共享
11  */
12  /**
13  * 线程范围内的共享:多个模块在同一个线程中运行时要共享一份数据
14  *
15  * 解决方式: 使用ThreadLocal---优雅版---将线程与数据分离
16  *
17  * @param
18  * @return
19  * @throws Exception
20  * @author ware E-mail:
21  * @version create time: 20172017年3月2日上午9:07:16
22  */
23 public class ThreadScopeShared4 {
24 //    private static ThreadLocal<Integer> local=new ThreadLocal<>();
25
26     public static void main(String[] args) {
27         for (int i = 0; i < 3; i++) {
28             new Thread(new Runnable() {
29                 @Override
30                 public void run() {
31 //                    int data=new Random().nextInt();
32 //                    local.set(data);
33
34                     ThreadScopeSharedData.getInstance().setAge(new Random().nextInt());
35                     ThreadScopeSharedData.getInstance().setName("vivi");
36                     new A().getNum();
37                     new B().getNum();
38                 }
39             }).start();
40         }
41
42     }
43
44     static class A{ // 模块A
45         public void getNum(){
46             int age=ThreadScopeSharedData.getInstance().getAge();
47             String name=ThreadScopeSharedData.getInstance().getName();
48             System.out.println(Thread.currentThread().getName()+"---------"+age);
49         }
50     }
51     static class B{ // 模块B
52         public void getNum(){
53             int age=ThreadScopeSharedData.getInstance().getAge();
54             String name=ThreadScopeSharedData.getInstance().getName();
55             System.out.println(Thread.currentThread().getName()+"---------"+age);
56         }
57     }
58 }
59
60 // 专门与线程绑定的对象
61 class ThreadScopeSharedData{
62     private ThreadScopeSharedData() {}
63     public static ThreadScopeSharedData getInstance(){
64         ThreadScopeSharedData instance=map.get();
65         if(instance==null){
66             instance=new ThreadScopeSharedData();
67             map.set(instance);
68         }
69         return instance;
70     }
71
72     private static ThreadLocal<ThreadScopeSharedData> map=new ThreadLocal<>();
73
74     private int age;
75     private String name;
76     public int getAge() {
77         return age;
78     }
79     public void setAge(int age) {
80         this.age = age;
81     }
82     public String getName() {
83         return name;
84     }
85     public void setName(String name) {
86         this.name = name;
87     }
88
89
90 }

时间: 2024-10-29 10:48:10

java多线程一览的相关文章

Java多线程系列--“JUC锁”11之 Semaphore信号量的原理和示例

概要 本章,我们对JUC包中的信号量Semaphore进行学习.内容包括:Semaphore简介Semaphore数据结构Semaphore源码分析(基于JDK1.7.0_40)Semaphore示例 转载请注明出处:http://www.cnblogs.com/skywang12345/p/3534050.html Semaphore简介 Semaphore是一个计数信号量,它的本质是一个"共享锁". 信号量维护了一个信号量许可集.线程可以通过调用acquire()来获取信号量的许可

从JAVA多线程理解到集群分布式和网络设计的浅析

对于JAVA多线程的应用非常广泛,现在的系统没有多线程几乎什么也做不了,很多时候我们在何种场合如何应用多线程成为一种首先需要选择的问题,另外关于java多线程的知识也是非常的多,本文中先介绍和说明一些常用的,在后续文章中如果有必要再说明更加复杂的吧,本文主要说明多线程的一下几个内容: 1.在应用开发中什么时候选择多线程? 2.多线程应该注意些什么? 3.状态转换控制,如何解决死锁? 4.如何设计一个具有可扩展性的多线程处理器? 5.多线程联想:在多主机下的扩展-集群? 6.WEB应用的多线程以及

java多线程心得

多并发的时候,在什么情况下必须加锁?如果不加锁会产生什么样的后果. 加锁的场景跟java的new thread和Runnable的关系是什么? 看看java的concurrentMap源码. 还有spring 的web.xml启动执行源码 spring aop http://www.cnblogs.com/FDROSE1001/p/3661895.html activemq的本质是什么? java的jms hibernate由配置文件映射到实体类的本质是什么? java反射 spring aop

Rhythmk 一步一步学 JAVA (21) JAVA 多线程

1.JAVA多线程简单示例 1.1 .Thread  集成接口 Runnable 1.2 .线程状态,可以通过  Thread.getState()获取线程状态: New (新创建) Runnable (可以运行) Blocked  (被阻塞) Waiting  (等待) Timed waiting (计时等待) Terminated  (被终止) ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27

(转载)Java多线程入门理解

转载出处http://blog.csdn.net/evankaka 写在前面的话:此文只能说是java多线程的一个入门,其实Java里头线程完全可以写一本书了,但是如果最基本的你都学掌握好,又怎么能更上一个台阶呢?如果你觉得此文很简单,那推荐你看看Java并发包的的线程池(Java并发编程与技术内幕:线程池深入理解),或者看这个专栏:Java并发编程与技术内幕.你将会对Java里头的高并发场景下的线程有更加深刻的理解. 目录(?)[-] 一扩展javalangThread类 二实现javalan

Java多线程系列--“JUC锁”02之 互斥锁ReentrantLock

ReentrantLock介绍 ReentrantLock是一个可重入的互斥锁,又被称为"独占锁". 顾名思义,ReentrantLock锁在同一个时间点只能被一个线程锁持有:而可重入的意思是,ReentrantLock锁,可以被单个线程多次获取.ReentrantLock分为"公平锁"和"非公平锁".它们的区别体现在获取锁的机制上是否公平."锁"是为了保护竞争资源,防止多个线程同时操作线程而出错,ReentrantLock在

synchronized与static synchronized 的差别、synchronized在JVM底层的实现原理及Java多线程锁理解

本Blog分为例如以下部分: 第一部分:synchronized与static synchronized 的差别 第二部分:JVM底层又是怎样实现synchronized的 第三部分:Java多线程锁,源码剖析 第一部分:synchronized与static synchronized的差别 1.synchronized与static synchronized 的差别 synchronized是对类的当前实例进行加锁,防止其它线程同一时候訪问该类的该实例的全部synchronized块.注意这里

深入聊聊Java多线程

一.背景 在没有学习Java多线程以前,总觉得多线程是个很神秘的东西,只有那些大神才能驾驭,新年假期没事就来学习和了解一下Java的多线程,本篇博客我们就来从头说一下多线程到底是怎么回事. 二.概述 1.进程的概念 每一个正在运行的程序都是一个进程,它是系统进行资源分配和调用的独立单位.且 每一个进程都有自己的内存空间和系统资源. 2.线程的概念 是进程中的单个顺序控制流,是一条执行路径.每个进程都可以拥有一个或者多个线程.各个线程之间都共享所属的那个进程的内存空间和系统资源. 3.单线程和多线

Java多线程 2 线程的生命周期和状态控制

一.线程的生命周期 线程状态转换图: 1.新建状态 用new关键字和Thread类或其子类建立一个线程对象后,该线程对象就处于新生状态.处于新生状态的线程有自己的内存空间,通过调用start方法进入就绪状态(runnable). 注意:不能对已经启动的线程再次调用start()方法,否则会出现Java.lang.IllegalThreadStateException异常. 2.就绪状态 处于就绪状态的线程已经具备了运行条件,但还没有分配到CPU,处于线程就绪队列(尽管是采用队列形式,事实上,把它