【JUC并发编程系列】JUC快速入门(一文读懂JUC)

本文深入讲解Java并发编程的基础概念,包括进程与线程的区别、线程的状态及其控制方法。此外,还介绍了Java并发工具包(JUC)的主要组件,如工具类、执行者模型、原子性类、锁机制和线程安全的集合类,并通过示例代码说明了Lock与synchronized关键字的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JUC概述

在Java中、线程是一个绕不过去的知识点、JUC是 java.util.concurrent工具包的简称、这是一个处理线程的工具包、JDK1.5开始出现的。

一、进程和线程详解

1.1、进程与线程

  • 进程:指在系统中正在进行的一个应用程序、程序一旦运行就是进程、进程资源分配的最小单位。
  • 线程:系统分配处理器时间资源的基本单位、或者说进程之内独立执行的一个单元执行流。线程-程序执行的最小单位

1.2、线程的状态

线程状态枚举类

public enum State {
        /**
         * Thread state for a thread which has not yet started.
         */
        NEW,

        /**
         * Thread state for a runnable thread.  A thread in the runnable
         * state is executing in the Java virtual machine but it may
         * be waiting for other resources from the operating system
         * such as processor.
         */
        RUNNABLE,

        /**
         * Thread state for a thread blocked waiting for a monitor lock.
         * A thread in the blocked state is waiting for a monitor lock
         * to enter a synchronized block/method or
         * reenter a synchronized block/method after calling
         * {@link Object#wait() Object.wait}.
         */
        BLOCKED,

        /**
         * Thread state for a waiting thread.
         * A thread is in the waiting state due to calling one of the
         * following methods:
         * <ul>
         *   <li>{@link Object#wait() Object.wait} with no timeout</li>
         *   <li>{@link #join() Thread.join} with no timeout</li>
         *   <li>{@link LockSupport#park() LockSupport.park}</li>
         * </ul>
         *
         * <p>A thread in the waiting state is waiting for another thread to
         * perform a particular action.
         *
         * For example, a thread that has called <tt>Object.wait()</tt>
         * on an object is waiting for another thread to call
         * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
         * that object. A thread that has called <tt>Thread.join()</tt>
         * is waiting for a specified thread to terminate.
         */
        WAITING,

        /**
         * Thread state for a waiting thread with a specified waiting time.
         * A thread is in the timed waiting state due to calling one of
         * the following methods with a specified positive waiting time:
         * <ul>
         *   <li>{@link #sleep Thread.sleep}</li>
         *   <li>{@link Object#wait(long) Object.wait} with timeout</li>
         *   <li>{@link #join(long) Thread.join} with timeout</li>
         *   <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
         *   <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
         * </ul>
         */
        TIMED_WAITING,

        /**
         * Thread state for a terminated thread.
         * The thread has completed execution.
         */
        TERMINATED;
    }

1.3、Wait和Sleep方法区别

1、Sleep是Thread的静态方法、wait是Object的方法、任何对象实例都能调用。
2、Sleep不会释放锁、也不需要占用锁。Wait会释放锁、当调用前提是当前线程占有锁(即代码要在Synchronized中)
3、他们都可以被Interrupted方法终端

二、JUC的结构

在这里插入图片描述

1、tools(工具类):又叫信号量三组工具类

1)CountDownLatch(闭锁) 是一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待
2)CyclicBarrier(栅栏) 之所以叫barrier,是因为是一个同步辅助类,允许一组线程互相等待,直到到达某个公共屏障点 ,并且在释放等待线程后可以重用。
3)Semaphore(信号量) 是一个计数信号量,它的本质是一个“共享锁“。信号量维护了一个信号量许可集。线程可以通过调用 acquire()来获取信号量的许可;当信号量中有可用的许可时,线程能获取该许可;否则线程必须等待,直到有可用的许可为止。 线程可以通过release()来释放它所持有的信号量许可。

2、executor(执行者):

是Java里面线程池的顶级接口,但它只是一个执行线程的工具,真正的线程池接口是ExecutorService,里面包含的类有:
1)ScheduledExecutorService 解决那些需要任务重复执行的问题
2)ScheduledThreadPoolExecutor 周期性任务调度的类实现

3、 atomic(原子性包):是JDK提供的一组原子操作类

包含有AtomicBoolean、AtomicInteger、AtomicIntegerArray等原子变量类,他们的实现原理大多是持有它们各自的对应的类型变量value,而且被volatile关键字修饰了。这样来保证每次一个线程要使用它都会拿到最新的值。

4、locks(锁包):

是JDK提供的锁机制,相比synchronized关键字来进行同步锁,功能更加强大,它为锁提供了一个框架,该框架允许更灵活地使用锁包含的实现类有:
1)ReentrantLock 它是独占锁,是指只能被独自占领,即同一个时间点只能被一个线程锁获取到的锁。
2)ReentrantReadWriteLock 它包括子类ReadLock和WriteLock。ReadLock是共享锁,而WriteLock是独占锁。
3)LockSupport 它具备阻塞线程和解除阻塞线程的功能,并且不会引发死锁。

5、collections(集合类):

主要是提供线程安全的集合, 比如:
1)ArrayList对应的高并发类是CopyOnWriteArrayList,
2)HashSet对应的高并发类是 CopyOnWriteArraySet,
3)HashMap对应的高并发类是ConcurrentHashMap等等

三、Lock锁(重点)

随着灵活性的增加,也带来了更多的责任。不使用块结构锁就失去了使用 synchronized 方法和语句时会出现的锁自动释放功能。在大多数情况下,应该使用以下语句:

     Lock l = ...; 
     l.lock();
     try {
         // access the resource protected by this lock
     } finally {
         l.unlock();
     }
 
锁定和取消锁定出现在不同作用范围中时,必须谨慎地确保保持锁定时所执行的所有代码用 try-finally 或 try-catch 加以保护,以确保在必要时释放锁。
/**
 * @ClassName: LSaleTicket
 * @Author: VV
 * @Version: 1.0.0
 * @Description: TODO
 * @MyEmail: vv1213418894@163.com
 * @CreateTime: 2022-09-12 16:48:39
 */
class LTicket{
    // 票数量
    private int number = 30;
    // 创建可重入锁
    private final ReentrantLock lock = new ReentrantLock();
    // 卖票方法
    public void sale(){
        try {
            lock.lock();
            if(number > 0){
                System.out.println(Thread.currentThread().getName() + ": 卖出" + (number--) + " 剩余 " + number);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 解锁
            lock.unlock();
        }
    }
}

public class LSaleTicket {

    public static void main(String[] args) {
        LTicket ticket = new LTicket();

        new Thread(() -> {
            for (int i = 0; i < 40; i++) {
                ticket.sale();
            }
        },"AA").start();

        new Thread(() -> {
            for (int i = 0; i < 40; i++) {
                ticket.sale();
            }
        },"BB").start();

        new Thread(() -> {
            for (int i = 0; i < 40; i++) {
                ticket.sale();
            }
        },"CC").start();

    }

}

Lock和Synchronized区别

  • Lock是一个接口、而Synchronized是Java中的关键字、Synchronized是内置语言实现。
  • Synchronized在发生异常时、会自动释放线程占有的锁、因此不会导致死锁现象发生、而Lock在发生异常时、如果没有主动通过unLock()去释放锁、则很可能造成死锁现象、因此使用Lock时需要在finally块中释放锁。
  • Lock可以让等待锁的线程响应中断、而synchronized却不行、使用synchronized时、等待的线程会一直等待下去、不能够响应中断。
  • 通过lock可以知道有没有成功获取锁、而synchronized无法办到
  • Lock可以提高多个线程进行读操作效率

四、集合的线程不安全

集合线程不安全演示

public static void main(String[] args) {
        List<Object> list = new ArrayList<>();

        for (int i = 0; i < 30; i++) {
            new Thread(() -> {
                list.add(UUID.randomUUID().toString().substring(0,8));
                System.out.println(list);
            },String.valueOf(i)).start();
        }
    }
java.util.ConcurrentModificationException
	at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:911)
	at java.util.ArrayList$Itr.next(ArrayList.java:861)
	at java.util.AbstractCollection.toString(AbstractCollection.java:461)
	at java.lang.String.valueOf(String.java:2994)
	at java.io.PrintStream.println(PrintStream.java:821)
	at com.atqianfen.thread.ThreadDemo02.lambda$main$0(ThreadDemo02.java:24)
	at java.lang.Thread.run(Thread.java:748)

源码

    /**
     * Appends the specified element to the end of this list (optional
     * operation).
     *
     * <p>Lists that support this operation may place limitations on what
     * elements may be added to this list.  In particular, some
     * lists will refuse to add null elements, and others will impose
     * restrictions on the type of elements that may be added.  List
     * classes should clearly specify in their documentation any restrictions
     * on what elements may be added.
     *
     * @param e element to be appended to this list
     * @return <tt>true</tt> (as specified by {@link Collection#add})
     * @throws UnsupportedOperationException if the <tt>add</tt> operation
     *         is not supported by this list
     * @throws ClassCastException if the class of the specified element
     *         prevents it from being added to this list
     * @throws NullPointerException if the specified element is null and this
     *         list does not permit null elements
     * @throws IllegalArgumentException if some property of this element
     *         prevents it from being added to this list
     */
    boolean add(E e);

集合线程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值