juc面试题

一:线程同步的方式有哪些?

线程同步指的就是让多个线程之间按照顺序访问同一个共享资源

  1. synchronized:Java中最基本的线程同步机制,可以修饰代码块或方法,保证同一时间只有一个线程访问该代码块或方法,其他线程需要等待锁的释放。
  2. ReentrantLock:可以保证同一时间只有一个线程访问共享资源,但是更灵活,支持公平锁、可中断锁、多个条件变量等功能。
  3. Semaphore:允许多个线程同时访问共享资源,但是限制访问的线程数量。可以用于控制并发访问的线程数量,避免系统资源被过度占用。
  4. CountDownLatch:允许一个或多个线程等待其他线程执行完毕之后再执行,可以用于线程之间的协调和通信。
  5. CyclicBarrier类:允许多个线程在一个栅栏处等待,直到所有线程都到达栅栏位置之后,才会继续执行。

二:Semaphore、CountDownLatch、CyclicBarrier区别?

它们都可以用来协调多个线程之间的执行。

  1. Semaphore是一个计数信号量,它允许多个线程同时访问共享资源,并通过计数器来控制访问数量。通常用来实现一个线程需要等待获取一个许可证才能访问共享资源,或者需要释放一个许可证才能完成操作的操作。
  2. CountDownLatch是一个计数器,通常用来实现一个线程等待其他多个线程完成操作之后再继续执行的操作。
  3. CyclicBarrier是一个同步屏障,通常用来实现多个线程在同一个屏障处等待,然后再一起继续执行的操作。

三:有三个线程T1,T2,T3如何保证顺序执行?

  1. 使用join:Thread类中提供了一个join方法,join就是把thread1这个子线程加入到当前主线程中,也就是主线程要阻塞在这里,等子线程执行完之后再继续执行。
    在这里插入图片描述

  2. Semaphore
    在这里插入图片描述
    在这里插入图片描述

  3. 使用CountDownLatch:主要就是想办法让编排三个子线程的主线程阻塞,保证T1执行完再启动T2,T2执行完再启动T3。而这个编排的方式就是想办法知道什么时候子线程执行完,就可以通过CountDownLatch实现。

在这里插入图片描述
在这里插入图片描述
4. 使用线程池:线程池内部是使用了队列来存储任务的,所以线程的执行顺序会按照任务的提交顺序执行的,但是如果是多个线程同时执行的话,是保证不了先后顺序的,因为可能先提交的后执行了。但是我们可以定义一个只有一个线程的线程池,然后依次的将T1,T2,T3提交给他执行:
在这里插入图片描述

四:三个线程分别顺序打印0-100

  1. Synchronized:结合Sync和Object#notifyAll来完成,如下所示
    在这里插入图片描述
    在这里插入图片描述

  2. ReentrantLock:我们可以使用ReentrantLock和Condition尝试解决这种问题。大概的解决思路就是先通过lock对资源加锁,然后通过condition指定的唤醒下一个线程,condition我们可以唤醒指定线程,避免资源浪费
    在这里插入图片描述
    在这里插入图片描述

在这里插入图片描述

五:有哪些实现线程安全的方案?

  1. 单线程
    想要实现线程安全,最简单的方式就是干脆不支持多线程,只用单线程来执行,那么就可以从根本上杜绝线程安全的问题了。比如Redis,就是这种思想,在命令执行时,只依赖单线程进行。
  2. 互斥锁
    如果一定要用多线程,比较有效的方式就是排队,那么加锁是一种比较常见的排队方式,无论是synchronized、reentrantLock这种单机锁,还是Redis实现的分布式锁,还是数据库中的乐观锁、悲观锁,本地思想都是通过加互斥锁的方式让多个并发请求排队执行。
  3. 原子操作
    原子操作是不可中断的操作,要么全部执行成功,要么全部失败。在多线程环境中,可以使用原子操作来实现对共享资源的安全访问,例如Java中的AtomicInteger等操作。
  4. 数据不共享
    像前面说的,如果没有共享数据,那么就不会有线程安全问题了,还有一种我们常用的手段来避免并发问题。那就是用ThreadLocal

六:父子线程之间怎么共享/传递数据?

  1. 自己传递:我们可以在子线程中创建一个成员变量,这样在主线程创建子线程的时候,可以给成员变量赋值,这样实现数据共享。
  2. InheritableThreadLocal:InheritableThreadLocal 可以在子线程中继承父线程中的值,这种方式有一个问题,那就是必须要是在主线程中手动创建的子线程才可以

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值