Java线程安全问题以及解决方式,附上例子以及代码,java架构师成长直通车

package ceshi;

/**

  • 线程安全使用排对机制 synchronized 同步锁

*/

public class Demo4 {

public static void main(String[] args) {

//多态的形式创建

Runnable runnable = new MyThread();

//三个线程进行卖票

new Thread(runnable).start();

new Thread(runnable).start();

new Thread(runnable).start();

}

static public class MyThread implements Runnable{

//假设有十张票

private int num = 10;

@Override

public void run() {

while (true){

//如果票数大于0则可以卖

if (num>0){

System.out.println(“准备出票”);

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

num–;

System.out.println(Thread.currentThread().getName()+“出票成功!还剩”+num);

}else {

break;

}

}

}

}

}

就会出现以下这种情况

Thread-1出票成功!

【一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义】

开源分享完整内容戳这里

还剩-1

Thread-2出票成功!还剩-2

Thread-0出票成功!还剩-1

这就是线程不安全导致的,

现在我们对其进行同步使用synchronized就会排队进行卖票。

static public class MyThread implements Runnable{

//假设有十张票

private int num = 10;

//同步锁

private Object o = new Object();

@Override

public void run() {

while (true){

//如果票数大于0则可以卖

synchronized (o){

if (num>0){

System.out.println(“准备出票”);

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

num–;

System.out.println(Thread.currentThread().getName()+“出票成功!还剩”+num);

}else {

break;

}

}

}

}

}

这样即可解决线程不安全问题,值得注意的是上锁的位置不可以如下图这样

public void run() {

Object o = new Object();

while (true){

//如果票数大于0则可以卖

synchronized (o){

if (num>0){

System.out.println(“准备出票”);

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

num–;

System.out.println(Thread.currentThread().getName()+“出票成功!还剩”+num);

}else {

break;

}

}

}

}

或者下图:

public void run() {

while (true){

//如果票数大于0则可以卖

Object o = new Object();

synchronized (o){

if (num>0){

System.out.println(“准备出票”);

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

num–;

System.out.println(Thread.currentThread().getName()+“出票成功!还剩”+num);

}else {

break;

}

}

}

}

这样相当于是锁在自己身上,并没有做到同步锁的要求,那么还是存在线程不安全的问题。

2.同步方法

如果不是静态的,synchronized的锁是this

如果是静态的,synchronized的锁是该类.class。

那么同步方法的实现代码如下:

主方法内容不变,实现接口的类里面将while判断的内容写成一个方法然后加上synchronized即可

static public class MyThread implements Runnable{

//假设有十张票

private int num = 10;

//同步锁

//private Object o = new Object();

@Override

public void run() {

while (true){

boolean flag = true;

flag = calculater();

if (!flag){

break;

}

}

}

/**

  • 同步方法 synchronized

  • @return

*/

public synchronized boolean calculater(){

//如果票数大于0则可以卖

if (num>0){

System.out.println(“准备出票”);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值