Java并发编程---线程安全问题

来源:互联网 发布:导航触摸屏校正软件 编辑:程序博客网 时间:2024/05/23 01:15

 1.线程安全的概念

      当多个线程访问某一个类(对象或方法)时,这个类始终都能表现出正确的行为,那么这个类(对象或方法)就是线程安全的.

      synchronized:可以在任意对象或方法上加锁,而加锁的这段代码称为"互斥区"或"临界区"


  #代码示例:

package com.thread.safety;/** * 线程安全小例子:多个线程竞争问题 * @author lhy * @time 2017.12.22 * */public class MyThread extends Thread {   private int count = 5;//synchronized加锁实现线程安全public synchronized void run(){count --;System.out.println(this.currentThread().getName() + "count = " + count);}/** * 执行机制分析:当多个线程访问MyThread的run方法时,以排队的方式进行处理(这里排队是按照CPU分配的先后顺序而定的) *    一个线程想要执行synchronized修饰的方法里的代码: *       1.尝试获得锁 *       2.如果拿到锁,执行synchronized代码体内容;拿不到锁,这个线程就会不断地尝试获得这把锁,直至拿到为止 *         而且是多个线程同时去竞争这把锁(也就是会产生锁竞争的问题) * @param args */public static void main(String[] args) {// TODO Auto-generated method stub        MyThread myThread = new MyThread();        Thread t1 = new Thread(myThread,"t1");        Thread t2 = new Thread(myThread,"t2");        Thread t3 = new Thread(myThread,"t3");        Thread t4 = new Thread(myThread,"t4");        Thread t5 = new Thread(myThread,"t5");        t1.start();        t2.start();        t3.start();        t4.start();        t5.start();}}

#代码分析:

当多个线程访问MyThread的run方法时,以排队的方式进行处理(这里排队是按照CPU分配的先后顺序而定的) ,一个线程想要执行synchronized修饰的方法里的代码,首先是尝试获得锁,如果拿到锁,执行synchronized代码体内容;拿不到锁,这个线程就会不断地尝试获得这把锁,直至拿到为止,而且是多个线程同时去竞争这把锁(也就是会产生锁竞争的问题)


2.多个线程多个锁问题

   概念:多个线程,每个线程都可以拿到自己指定的锁,分别获得锁之后,执行synchronized方法体的内容


  #代码示例

package com.thread.safety;/** * 多个线程多个锁问题 *  * @author lhy * @time 2017.12.22 * */public class MultiThread {/** * 关键字synchronized取得的锁都是对象锁,而不是把一段代码(方法)当做锁, * 所以代码中哪个线程先执行synchronized关键字的方法,哪个线程就持有该方法所属对象的的锁(Lock) *  * 在静态方法上加synchronized关键字,表示锁定.class类,类一级别的锁(独占.class类) */private static int num = 0;//加static相当于在对象上加了一把锁public synchronized void printNum(String tag) {try {if (tag.equals("a")) {num = 100;System.out.println("tag a , set num Over!");Thread.sleep(1000);}else {num = 200;System.out.println("tag b , set num Over!");}System.out.println("tag" + tag + ", num = " + num);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}//注意观察run方法输出顺序public static void main(String[] args) {//两个不同的对象final MultiThread m1 = new MultiThread();        final MultiThread m2 = new MultiThread();                Thread t1 = new Thread(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubm1.printNum("a");}});                Thread t2 = new Thread(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubm2.printNum("b");}});                t1.start();        t2.start();}}


#代码分析:

       关键字synchronized取得的锁都是对象锁,而不是把一段代码(方法)当做锁,所以示例代码中哪个线程先执行synchronized关键字的方法,哪个线程就持有该方法所属对象的的锁(Lock).两个对象,线程获得的就是两个不同的锁,他们互不影响.

      有一种情况则是相同的锁:即在静态方法上加synchronized关键字,表示锁定.class类,类一级别的锁(独占.class类)

阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 打吊瓶的危害 打吊瓶 挂吊瓶的危害 为什么氯化钾点滴会痛 点火公式 点火线圈 偏时点火 点火提前角 脉冲点火器 点火系统 点火器 煽风点火 点火 摩托车点火 梦见点火 脉冲点火 军运会点火 军运点火 热水器点火 汽车点火 扇风点火 壁挂炉点火 点火针 点火线 点火头 点火锁 点火电极 汽车点火线 电子点火 等离子点火 点火提前器 点火增强器 锅炉点火 天然气点火 自动挡点火 点火系 点火针价格 白金点火 点火困难 手动挡点火 燃气灶点火