(4)Java多线程之安全问题-下
来源:互联网 发布:suse12 linux 网卡配置 编辑:程序博客网 时间:2024/05/24 05:36
- 引言
- Java多线程中的类锁
- 1 注意区分类锁和对象锁的区别
- Java中的死锁现象
- 1 最低级的线程死锁现象
- volatile关键字
- 1 同步死循环问题
- 2 解决死循环记住
1.引言
在此篇博客中,主要介绍一下,在Java多线程中的:类锁,死锁,以及volatile
关键字。
2.Java多线程中的类锁
在上一篇博客中我们使用了下面的代码:
public synchronized boolean saleTicket() throws Exception { //代码 }
在上篇博客中我们介绍了,这样其实就是给该方法加锁:加的是对象锁,对象就是this注意: 1.该方法不是静态方法,如果是静态方法呢?静态方法就不是this了。 2.这很好理解,如果是静态方法,在私用该方法的时候,说不定都没有this对象
- 现在我们把代码改成这样(方法变成了静态方法)
public synchronized static void saleTicket() { System.out.println("我在卖票了"); }
上述代码等价于
public class Ticket { public static void saleTicket() { synchronized (Ticket.class) { System.out.println("我在卖票了"); } }}
此时我们是给方法添加了一个类锁。
2.1 注意区分类锁和对象锁的区别
public class Ticket { public synchronized static void saleTicket1() { System.out.println("我在卖票了"); } public synchronized void saleTicket2() { System.out.println("我在卖票了"); }}
注意: 1.这两个方法给对象加的锁是不一样的,一个是类锁,一个是this对象锁 2.当线程1访问saleTicket1方法的同时拿到类锁 3.当线程2访问saleTicket2是要拿this对象锁(哪怕线程1未释放锁)。两者是不影响的
3. Java中的死锁现象
在Java多线程编程当中,一定要避免死锁现象。死锁现象一产生很容易造成线程假死现象。这种错误是非常难排查的。
3.1 最低级的线程死锁现象
- 代码如下
public class Ticket { private Object o1=new Object(); private Object o2=new Object(); public void saleTicket1() { synchronized (o1) { System.out.println("拿到o1"); synchronized (o2) { System.out.println("拿到o2"); } } } public void saleTicket2() { synchronized (o2) { System.out.println("拿到o2"); synchronized (o1) { System.out.println("拿到o1"); } } }}
1.如果线程1访问saleTicket1方法。线程2访问saleTicket2方法2.线程1拿到o1锁,线程2拿到o2锁,此时线程1等待o2锁,线程2等待o1锁:导致死锁3.线程死锁是程序设计时的bug,我们应该尽量避免死锁现象的产生
4.volatile关键字
关键字volatile解决的问题主要是:变量在多个线程间可见。
4.1 同步死循环问题
- 首先我们创建一个打印字符串的类
public class PrintString { private boolean flag = true; public void setFlag(boolean flag) { this.flag = flag; } public void printString() { while (flag) { System.out.println("打印字符串"); } }}
- 输入字符串的线程类
public class MyThread extends Thread { PrintString p; public MyThread(PrintString p) { this.p=p; } @Override public void run() { p.printString(); }}
- main函数
public class app { public static void main(String[] args) throws InterruptedException { PrintString p=new PrintString(); MyThread td=new MyThread(p); td.start(); Thread.sleep(5000); p.setFlag(false); }}
- 如果我们以服务器模式运行,这就是一个死循环
-server
4.2 解决死循环(记住)
- 只需要给共享数据添加一个关键字即可
public class PrintString { volatile private boolean flag = true; public void setFlag(boolean flag) { this.flag = flag; } public void printString() { while (flag) { System.out.println("打印字符串"); } }}
1 0
- (4)Java多线程之安全问题-下
- (3)Java多线程之安全问题-上
- java笔记之java多线程的安全问题
- java多线程学习之线程安全问题
- Java Tread多线程(2)多线程安全问题
- Java多线程设计(三)线程安全问题
- java多线程及安全问题
- Java 多线程的安全问题
- java多线程安全问题
- Java多线程--安全问题
- Java多线程安全问题
- java中的多线程安全问题
- Java 多线程 线程安全问题
- Java多线程探究-多线程安全问题
- 黑马程序员——Java多线程之线程安全问题
- java多线程学习之通过synchronized加锁解决线程安全问题
- Java——多线程安全问题
- java 学习-----多线程的安全问题
- 【数据结构】-线性表-链表 熟练度max=4(split)
- mybaits错误解决:There is no getter for property named 'id' in class 'java.lang.String'
- 彻底理解java语言的线程安全volatile用法
- c指针学习
- target runtime apache v7.0 not defined
- (4)Java多线程之安全问题-下
- 15位和18位身份证JS校验实例(jquery)和注意事项
- 文章标题
- Intellij IDEA 内存优化
- [WZOI D1T2] 挑选士兵
- Android 使用Rtmp音视频推流
- 线性表链式存储实现
- R语言学习十一
- openvpn-2.3.8开通客户端