【Code】4种常用Java线程锁的特点,性能比较、使用场景

文章目录

  • 文章说明
  • 原文链接
  • 4种Java线程锁(线程同步)
    • 1.synchronized
      • synchronized修饰同步代码块
      • synchronized修饰方法
      • synchronized修饰对象
      • 测试代码
    • 2.ReentrantLock
    • 3.Semaphore
    • 4.AtomicInteger

文章说明

本文是对相关主题文章的代码功能展示,主要通过代码形式来验证和演示功能,以加深对知识点的理解。如有遗漏或理解不正确的地方,欢迎大家拍砖!

原文链接

【转载】4种常用Java线程锁的特点,性能比较、使用场景

4种Java线程锁(线程同步)

1.synchronized

synchronized有以下几种用法:

synchronized修饰同步代码块


import lombok.extern.slf4j.Slf4j;

@Slf4j
public class SynCodeAreaThread implements Runnable
{
    static int num = 100;
    
    /**
     * synchronized修饰同步代码块
     */
    @Override
    public void run()
    {
        synchronized (this)
        {
            if (num > 0)
            {
                log.info("{} ==> num: {}", Thread.currentThread().getName(), num);
                num--;
            }
        }
    }
}

synchronized修饰方法


import lombok.extern.slf4j.Slf4j;

@Slf4j
public class SynMethodThread implements Runnable
{
    static int num = 100;
    
    @Override
    public void run()
    {
        sell();
    }
    
    /**
     * synchronized修饰方法
     * 
     * @see [类、类#方法、类#成员]
     */
    private synchronized void sell()
    {
        if (num > 0)
        {
            log.info("{} ==> num: {}", Thread.currentThread().getName(), num);
            num--;
        }
    }
}

synchronized修饰对象


import lombok.extern.slf4j.Slf4j;

@Slf4j
public class SynObjThread implements Runnable
{
    static int num = 100;
    
    /**
     * lock零长度的byte数组对象创建起来将比任何对象都经济
     */
    private byte[] lock = new byte[0];
    
    /**
     * synchronized修饰对象
     */
    @Override
    public void run()
    {
        synchronized (lock)
        {
            if (num > 0)
            {
                log.info("{} ==> num: {}", Thread.currentThread().getName(), num);
                num--;
            }
        }
    }
}

测试代码

/**
 * 
 * synchronized线程锁测试
 * 
 * @author 00fly
 */
@RunWith(SpringRunner.class)
public class SynThreadLockTest
{
    ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
    
    @Test
    public void testSynObjThread()
        throws InterruptedException
    {
        Runnable runnable = new SynObjThread();
        IntStream.range(0, 100).forEach(num -> cachedThreadPool.execute(runnable));
    }
    
    @Test
    public void testSynMethodThread()
    {
        Runnable runnable = new SynMethodThread();
        IntStream.range(0, 100).forEach(num -> cachedThreadPool.execute(runnable));
    }
    
    @Test
    public void testSynCodeAreaThread()
    {
        Runnable runnable = new SynCodeAreaThread();
        IntStream.range(0, 100).forEach(num -> cachedThreadPool.execute(runnable));
    }
}

2.ReentrantLock


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

import lombok.extern.slf4j.Slf4j;

/**
 * 公平锁的实现就是谁等待时间最长,谁就先获取锁
* 非公平锁就是随机获取
* ReentrantLock给定参数为(true)则为公平锁 * * @author 00fly * @version [版本号, 2022年12月16日] * @see [相关类/方法] * @since [产品/模块版本] */
@Slf4j public class ReentrantLockThread implements Runnable { static int num = 100; Lock lock = new ReentrantLock(); @Override public void run() { lock.lock(); try { if (num > 0) { log.info("{} ==> num: {}", Thread.currentThread().getName(), num); num--; } } finally { lock.unlock(); } } }

/**
 * 
 * ReentrantLock线程锁测试
 * 
 * @author 00fly
 */
@RunWith(SpringRunner.class)
public class ReentrantLockTest
{
    ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
    
    @Test
    public void testReentrantLockThread()
    {
        Runnable runnable = new ReentrantLockThread();
        IntStream.range(0, 100).forEach(num -> cachedThreadPool.execute(runnable));
    }
}

3.Semaphore


import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class SemaphoreThread implements Runnable
{
    // 表示有2个许可.
    Semaphore sem = new Semaphore(2);
    
    @Override
    public void run()
    {
        try
        {
            sem.acquire(); // 默认使用一个许可.
            log.info("{} I get it.", Thread.currentThread());
            TimeUnit.SECONDS.sleep(3);
            log.info("{} I release it.", Thread.currentThread());
        }
        catch (InterruptedException e)
        {
            log.error(e.getMessage());
        }
        finally
        {
            sem.release();
        }
    }
}


/**
 * 
 * ReentrantLock线程锁测试
 * 
 * @author 00fly
 */
@RunWith(SpringRunner.class)
public class ReentrantLockTest
{
    ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
    
    @Test
    public void testReentrantLockThread()
    {
        Runnable runnable = new ReentrantLockThread();
        IntStream.range(0, 100).forEach(num -> cachedThreadPool.execute(runnable));
    }
}

4.AtomicInteger


import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.commons.lang3.RandomUtils;
import org.springframework.util.StopWatch;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class AtomicIntegerThread implements Runnable
{
    private AtomicInteger count = new AtomicInteger(0);
    
    @Override
    public void run()
    {
        if (count.get() >= 5)
        {
            log.info("请求用户过多,请稍后再试! 计数器:{}", count.get());
            return;
        }
        try
        {
            log.info("业务处理开始,计数器自增:{}", count.incrementAndGet());
            
            // 模拟耗时业务操作
            log.info("★★★★★★★★ 报名或抢购处理中★★★★★★★★");
            StopWatch clock = new StopWatch();
            clock.start();
            TimeUnit.MILLISECONDS.sleep(RandomUtils.nextInt(10000, 20000));
            clock.stop();
            log.info("运行 {} ms ---------------", clock.getLastTaskTimeMillis());
        }
        catch (InterruptedException e)
        {
            log.error(e.getMessage());
        }
        finally
        {
            log.info("业务处理完毕,计数器自减:{}", count.decrementAndGet());
        }
    }
}


/**
 * 
 * AomicInteger计数器限流示例
 * 
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
public class AtomicIntegerTest
{
    /**
     * 线程池方式测试
     * 
     * @throws InterruptedException
     * @see [类、类#方法、类#成员]
     */
    @Test
    public void test()
        throws InterruptedException
    {
        ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
        Runnable runnable = new AtomicIntegerThread();
        while (true)
        {
            TimeUnit.MILLISECONDS.sleep(RandomUtils.nextInt(100, 1000));
            cachedThreadPool.execute(runnable);
        }
    }
}

你可能感兴趣的:(转载/Code,java,线程锁)