Java中的同步机制解决线程安全问题

Java中的同步机制解决线程安全问题

什么是线程安全呢?就是我们开启多线程的时候,如何解决并发的问题,比如之前的买火车票问题,出现了不同的窗口卖同一张票的现象,那么这个是不允许的,这个就是资源占用的问题,如果想出一个方法,能让窗口1卖这一张票,另外的只能等待,这样就解决了上述的问题了。那么,在Java中有三种常见的方法解决线程安全。


  1. 同步代码块

    所谓的同步代码块就是用synchronized 关键字可以用于方法中的某个区块中,表示只对这个区块的资源实行互斥访问。

    public class TiceketSold implements Runnable{
    
        //定义一个票数
        int num = 10;
    
        Object lock = new Object();
    
        @Override
        public void run() {
            while (true){
               synchronized (lock){
                   //模拟卖票的时间(100ms)
                   if (num == 0){
                       break;
                   }
                   try {
                       Thread.sleep(100);
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
                   System.out.println(Thread.currentThread().getName()+"正在卖第"+num--+"张票");
               }
    
            }
        }
    
        public static void main(String[] args) {
            TiceketSold tk = new TiceketSold();
    
            new Thread(tk,"xiao").start();
            new Thread(tk,"xddd").start();
            new Thread(tk,"xggg").start();
    
        }
    
    }
    
  2. 同步方法

    这个其实类似于上面,不过是用一个方法将有哦线程安全的代码抽离出来写一个方法,然后使用的时候调用这个方法即可。

    public class TiceketSold01 implements Runnable{
    
        //定义一个票数
        int num = 10;
    
    
    
        @Override
        public void run() {
            soldTicket();
        }
    
        //同步方法
        public synchronized void soldTicket(){
            while (true){
                //模拟卖票的时间(100ms)
                if (num == 0){
                    break;
                }
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"正在卖第"+num--+"张票");
            }
    
        }
    
        public static void main(String[] args) {
            TiceketSold01 tk = new TiceketSold01();
    
            new Thread(tk,"xiao").start();
            new Thread(tk,"xddd").start();
            new Thread(tk,"xggg").start();
    
        }
    
    }
    
  3. Lock锁

    java.util.concurrent.locks.Lock 机制提供了比synchronized代码块和synchronized方法更广泛的锁定操作,同步代码块/同步方法具有的功能Lock都有,除此之外更强大,更体现面向对象。

    Lock锁也称同步锁,加锁与释放锁方法化了,如下:

    public void lock() :加同步锁。

    public void unlock() :释放同步锁。

    public class TiceketSold02 implements Runnable{
    
        //定义一个票数
        int num = 10;
        Lock lock = new ReentrantLock();//定义lock对象
        @Override
        public void run() {
            while (true){
    
    
                   //模拟卖票的时间(100ms)
    
                lock.lock();//加锁
                   try {
                       if (num == 0){
                           break;
                       }
                       Thread.sleep(100);
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
                   System.out.println(Thread.currentThread().getName()+"正在卖第"+num--+"张票");
    
                   lock.unlock();//释放锁
            }
        }
    
        public static void main(String[] args) {
            TiceketSold02 tk = new TiceketSold02();
    
            new Thread(tk,"xiao").start();
            new Thread(tk,"xddd").start();
            new Thread(tk,"xggg").start();
    
        }
    
    }
    

猜你喜欢

转载自blog.csdn.net/qq_39594037/article/details/107176056