Java线程安全函数_java 多线程安全--- synchronized 关键字

1.什么线程安全问题?

1.1 就是当多个线程共享同一个全局变量,同时对这个变量做写的时间,可能会受到其他线程的干扰,导致数据有误。

class ThreadDemos implements Runnable {

private int movie = 8;

@Override

public void run() {

while (movie > 0) {

try {

Thread.sleep(10);

} catch (Exception e) {

// TODO: handle exception

}

sell();

}

}

public void sell() {

if (movie > 0) {

System.out.println(Thread.currentThread().getName() + ",出售第" + (8 - movie + 1) + "票");

movie--;

}

}

}

public class ThreadDemo {

public static void main(String[] args) {

ThreadDemos threadDemos = new ThreadDemos();

Thread t1 = new Thread(threadDemos, "美团买票");

Thread t2 = new Thread(threadDemos, "门店买票");

t1.start();

t2.start();

}

}

运行结果:

5d59a07b78719575b7ccd18a5c205c15.png

由此我们可以发现2个窗口会出现同一张票,就出现了线程安全问题,如果2个不同的人买了同一张票,这个时间检票员是该让哪个人进去看电影那?

2.怎么样解决线程安全问题?

2.1 使用synchronized 同步代码块  代码如下:

class ThreadDemos implements Runnable {

private int movie = 8;

private Object object = new Object();

@Override

public void run() {

while (movie > 0) {

try {

Thread.sleep(10);

} catch (Exception e) {

// TODO: handle exception

}

sell();

}

}

public void sell() {

synchronized (object) {

if (movie > 0) {

System.out.println(Thread.currentThread().getName() + ",出售第" + (8 - movie + 1) + "票");

movie--;

}

}

}

}

public class ThreadDemo {

public static void main(String[] args) {

ThreadDemos threadDemos = new ThreadDemos();

Thread t1 = new Thread(threadDemos, "美团买票");

Thread t2 = new Thread(threadDemos, "门店买票");

t1.start();

t2.start();

}

}

代码运行结果:

9fd37dd5ef2b984bf9e1df1bcc8101d9.png

使用 synchronized 同步代码块 就不会出现2个窗口会出现同一张票的安全性问题

使用synchronized 的  条件:1.必须要有2个线程以上的,需要同步  2.多个线程想要同步,必须要使用同一把锁 3.保证只有一个线程运行执行

使用synchronized 同步代码块 的原理:有一个线程已经拿到锁了,其他线程已经有cpu执行的,那么这个线程会等待拿到锁的那个线程执行完毕释放锁

使用synchronized 的缺点:效率低,因为线程会抢锁

2.2使用 同步函数解决线程安全:

class ThreadDemos implements Runnable {

private int movie = 8;

@Override

public void run() {

while (movie > 0) {

try {

Thread.sleep(10);

} catch (Exception e) {

// TODO: handle exception

}

sell();

}

}

public synchronized void sell() {

if (movie > 0) {

System.out.println(Thread.currentThread().getName() + ",出售第" + (8 - movie + 1) + "票");

movie--;

}

}

}

public class ThreadDemo05 {

public static void main(String[] args) {

ThreadDemos threadDemos = new ThreadDemos();

Thread t1 = new Thread(threadDemos, "美团买票");

Thread t2 = new Thread(threadDemos, "门店买票");

t1.start();

t2.start();

}

}

代码运行结果:

e81680f7e266a7cc040f8e79db75de5f.png

使用同步函数 在需要同步的方法上面加上  synchronized 关键字,同步函数使用的是 this 锁

2.3使用静态同步函数

class ThreadDemos implements Runnable {

private static int movie = 8;

@Override

public void run() {

while (movie > 0) {

try {

Thread.sleep(10);

} catch (Exception e) {

// TODO: handle exception

}

sell();

}

}

public static synchronized void sell() {

if (movie > 0) {

System.out.println(Thread.currentThread().getName() + ",出售第" + (8 - movie + 1) + "票");

movie--;

}

}

}

public class ThreadDemo05 {

public static void main(String[] args) {

ThreadDemos threadDemos = new ThreadDemos();

Thread t1 = new Thread(threadDemos, "美团买票");

Thread t2 = new Thread(threadDemos, "门店买票");

t1.start();

t2.start();

}

}

运行结果:

1d65410c59ae70fbd5cd6df8c5229851.png

静态同步函数使用的是 当前字节码文件

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值