原创

Lock(ReentrantLock)实现线程同步,线程安全

多线程实现同步机制的方式有3种

1.synchronized作用在方法上

弊端:方法上面的锁是this,如果两个线程的实例不是一个,不能锁住

2.synchronized作用在代码块的方式

3.Lock的实现(ReentrantLock)的作用在任意代码

与synchronized的区别是synchronized是隐式锁,不需要明确声明锁打开与关闭
ReentrantLock是显示锁,需要自己打开锁的范围,自己关掉锁的范围

以下代码中有使用Callable的方式创建线程的,因为FutureTask有CAS的线程安全机制,它本身可以解决线程安全的问题

代码实现:

package com.example.demo.juc;

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

public class TestLock {
    public static void main(String[] args) {
        TicketR ticketR = new TicketR();
//        Ticket ticket = new Ticket();
        //FutureTask本身利用了CAS实现了线程安全
//        FutureTask<Object> futureTask = new FutureTask<Object>(ticket);
//
//        new Thread(futureTask,"1号窗口").start();
//        new Thread(futureTask,"2号窗口").start();
//        new Thread(futureTask,"3号窗口").start();



//
        new Thread(ticketR,"1号窗口").start();
        new Thread(ticketR,"2号窗口").start();
        new Thread(ticketR,"3号窗口").start();
    }
}

class Ticket implements Callable {

    private int ticket = 100;

    @Override
    public Object call() throws Exception {
        while(true) {
            try{
                Thread.sleep(200);
            }catch(Exception e){
                e.printStackTrace();
            }
            if (ticket > 0) {
                System.out.println(Thread.currentThread().getName() + ": 余票为: " + --ticket);
            }
        }
    }
}

class TicketR implements Runnable {

    private int ticket = 100;

    private Lock lock = new ReentrantLock();

    @Override
    public void run()  {
        while(true) {
            try {
                lock.lock();
                try {
                    Thread.sleep(200);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (ticket > 0) {
                    System.out.println(Thread.currentThread().getName() + ": 余票为: " + --ticket);
                }
            }finally {
                lock.unlock();
            }
        }
    }
}
正文到此结束
本文目录