常说的java加锁有哪三种方法

Posted 石工记

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了常说的java加锁有哪三种方法相关的知识,希望对你有一定的参考价值。

1、synchronized方式(重量级锁)

加锁方式:synchronized(object)传入对象,不同对象代表不同锁,可以在线程外部新建对象。

public class SellCinemaTicketThread implements Runnable 
    static int num = 100;
    Object object = new Object();

    @Override
    public void run() 
        while (true) 
            synchronized (object) 
                if (num > 0) 
                    System.out.println(Thread.currentThread().getName() + "买票啦---" + num);
                    num--;
                
            

        
    

也可以作为方法的修饰传入

public class SellCinemaTicketThread1 implements Runnable 
    static int num = 100;

    @Override
    public void run() 
        sell();
    

    private synchronized void sell() 
        while (true) 
            if (num > 0) 
                System.out.println(Thread.currentThread().getName() + "买票啦---" + num);
                num--;
            
        
    

2、Lock(比synchronized要轻量级)

  • 新建锁对象Lock l = new ReentrantLock();
  • 加锁 l.lock()
  • 解锁 l.unlock()
public class TestLockSellTicket implements Runnable 
    static int num = 100;
    Lock l = new ReentrantLock();

    @Override
    public void run() 
        while (true) 
            l.lock();
            if (num > 0) 
                try 
                    Thread.sleep(100);
                    System.out.println("买票啦---" + num);
                    num--;
                 catch (InterruptedException e) 
                    e.printStackTrace();
                 finally 
                    l.unlock();
                

            

        

    

3、wait() notify() notifyAll()

/*
wait() notify() notifyAll() 是Object上的方法,只有Object是对象监视器时候才能调用此方法
    notify() 唤醒同一个对象监视器上的线程

    wait(Long timeout) 传入数值,表示超过某个时间还没有被唤醒则自动唤醒

    wait和sleep区别:
        sleep() 可以在同步中和同步外使用,线程遇到sleep不释放锁,时间到了继续向下执行
        wait() 只能在同步中使用,由对象监视器调用, 线程进入wait状态时释放掉锁

*/
public class TestWaitAndNotify 
    public static void main(String[] args) 
        Object obj = new Object();
        new Thread(new Runnable() 
            @Override
            public void run() 
                synchronized (obj) 
                    System.out.println("开始等待。。。。");
                    try 
                        obj.wait();
                     catch (InterruptedException e) 
                        e.printStackTrace();
                    
                    System.out.println("等待结束。。。。");
                
            
        ).start();

        new Thread(new Runnable() 
            @Override
            public void run() 
                synchronized (obj) 
                    // 休眠两秒再唤醒线程
                    try 
                        Thread.sleep(2000);
                     catch (InterruptedException e) 
                        e.printStackTrace();
                    
                    obj.notify();
                
            
        ).start();
    


买票加锁

SellCinemaTicketThread1类


public class SellCinemaTicketThread1 implements Runnable 
    static int num = 100;

    @Override
    public void run() 
        sell();
    

    private synchronized void sell() 
        while (true) 
            if (num > 0) 
                System.out.println(Thread.currentThread().getName() + "买票啦---" + num);
                num--;
            
        
    

TestSellCinemaTicket 买票类 多个线程同时卖票

/*

保持同步:
    代码块加锁  synchronized (任意对象即对象锁) 需要同步的对象
    方法加锁 在方法返回值前加synchronized
        private synchronized void sell() 同步代码
*/

public class TestSellCinemaTicket 
    public static void main(String[] args) 
//        Runnable r = new SellCinemaTicketThread();
        Runnable r = new SellCinemaTicketThread1();

        Thread t1 = new Thread(r);
        Thread t2 = new Thread(r);
        Thread t3 = new Thread(r);

        t1.start();
        t2.start();
        t3.start();

    

以上是关于常说的java加锁有哪三种方法的主要内容,如果未能解决你的问题,请参考以下文章

Java常见面试题(第六弹):分布式锁的实现方式有哪三种?

python基本结构有哪三种

有限状态机的状态编码风格主要有哪三种

企业信息平台运维管理体系的搭建方法有哪三种

sql server使用不同的锁模式锁定资源,这些模式有哪三种

python都有哪些数据类型