线程安全

线程安全

1. 同步代码块:

通过在类里私有对象,锁住synchronized所包含的区域
格式:synchronized(锁对象){}

package xc;

public class Demo8 {
    public static void main(String[] args) {
        Runnable t = new Ticket();
        new Thread(t).start();
        new Thread(t).start();
        new Thread(t).start();
    }

    static class Ticket implements Runnable {
        //票数
        private int count = 10;
        private Object o = new Object();

        @Override
        public void run() {
            while (count > 0) {
                synchronized (o) {
                    System.out.println(Thread.currentThread().getName() + "正在买票");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    count--;
                    System.out.println("卖票成功,还有票数:" + count);
                }
            }
        }
    }
}

2. 同步方法

以方法为单位,把synchronized修饰到方法里

public synchronized boolean sate() {}

package xc;

public class Demo8 {
    public static void main(String[] args) {
        Runnable t = new Ticket();
        new Thread(t).start();
        new Thread(t).start();
        new Thread(t).start();
    }

    static class Ticket implements Runnable {
        //票数
        private int count = 10;
        //private Object o = new Object();

        @Override
        public void run() {
            while (true) {
                boolean flag = sate();
                if(!flag){
                    break;
                }
//                synchronized (o) {
//                    System.out.println(Thread.currentThread().getName() + "正在买票");
//                    try {
//                        Thread.sleep(1000);
//                    } catch (InterruptedException e) {
//                        e.printStackTrace();
//                    }
//                    count--;
//                    System.out.println("卖票成功,还有票数:" + count);
//                }
            }
        }

        //把需要同步的内容定义成一个方法
        public synchronized boolean sate() {
            if (count > 0) {
                System.out.println(Thread.currentThread().getName() + "正在买票");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                count--;
                System.out.println("卖票成功,还有票数:" + count);
                return true;
            }else {
                return false;
            }
        }
    }
}

3.显示锁

将锁创建出来
Lock s = new ReentrantLock();
s.lock();锁住
s.unlock();解开

package xc;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Demo9 {
    public static void main(String[] args) {
        Runnable t = new Ticket();
        new Thread(t).start();
        new Thread(t).start();
        new Thread(t).start();
    }

    static class Ticket implements Runnable {
        //票数
        private int count = 10;
        //锁
        Lock l = new ReentrantLock();

        @Override
        public void run() {

            while (true) {
                l.lock();
                if (count > 0) {

                    System.out.println(Thread.currentThread().getName() + "正在买票");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    count--;
                    System.out.println("卖票成功,还有票数:" + count);
                    l.unlock();
                } else {
                    break;
                }
            }
        }
    }
}

前两个是隐式锁,最后一个是隐式锁

一、隐式锁
隐式锁中又分为同步代码块和同步方法,但是都是基于Synchronized关键字来实现的,因为他只需要是使用管关键字就可以,不用显示加锁和解锁的过程,所以称之为隐式锁。

二、显示锁Lock
显式锁的概念是相对于隐式锁的,因为显式锁在使用的时候程序员可以控制上锁和解锁,所以称之为显式锁。

区别:

1、内存泄漏
隐式锁:简单易用且不会导致内存泄漏。
显式锁:完全要程序员控制,容易导致锁泄露。

2、是否可中断
隐式锁:不可中断的。除非抛出异常或者正常运行完成
显式锁:可以中断。

7、精确唤醒
隐式锁:不能精确唤醒一个线程。要么随机唤醒一个线程;要么是唤醒所有等待的线程。
显式锁:能精确唤醒一个线程。实现分组唤醒需要唤醒的线程。

四、共同点

1、无论是显式锁还是隐式锁,当被锁住的代码块执行结束以后,正在等待的线程 开始抢时间偏执行代码块,并不是先来后到的方式进行执行,而是随机的的抢到时间偏就执行。

2、被锁住的代码块,谁先抢到时间偏进行代码执行以后,再次抢到的概率会增加,连续抢到的概率很大。

3、都可以解决线程安全问题

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fun灬小鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值