Java线程操作JUC相关笔记

JUC

volatile 关键字

  • volatile 关键字: 当多个线程进行操作共享数据时,可以保证内存中的数据是可见的;相较于 synchronized是一种
    较为轻量级的同步策略;
  • volatile 不具备"互斥性";
  • volatile 不能保证变量的"原子性";

CAS算法

  • CAS(Compare-And-Swap) 算法是硬件对于并发的支持,针对多处理器操作而设计的处理器中的一种特殊指令,用于管理对共享数据的并发访问;
  • CAS 是一种无锁的非阻塞算法的实现;
    • 需要读写的内存值: V
    • 进行比较的预估值: A
    • 拟写入的更新值: B
    • 当且仅当 V == A 时, V = B, 否则,将不做任何操作;

并发容器类

Java 5.0 在 java.util.concurrent 包中提供了多种并发容器类来改进同步容器的性能;

ConcurrentHashMap

1、ConcurrentHashMap:ConcurrentHashMap就是一个线程安全的hash表。我们知道HashMap是线程不安全的,Hash Table加了锁,是线程安全的,因此它效率低。HashTable加锁就是将整个hash表锁起来,当有多个线程访问时,同一时间只能有一个线程访问,并行变成串行,因此效率低。

CountDownLatch(闭锁)

CountDownLatch是一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待;

// 一个简单的例子:利用CountDownLatch辅助类计算所有是个子线程的执行时间
    public class TestCountDownLatch {
        public static void main(String[] args) {
            final CountDownLatch latch = new CountDownLatch(10);//有多少个线程这个参数就是几
            LatchDemo ld = new LatchDemo(latch);
            long start = System.currentTimeMillis();
            for (int i = 0; i < 10; i++) {
                new Thread(ld).start();
            }
            try {
                latch.await();//这10个线程执行完之前先等待
            } catch (InterruptedException e) {
            }
            long end = System.currentTimeMillis();
            System.out.println("耗费时间为:" + (end - start));
        }
    }
    
    class LatchDemo implements Runnable {
        private CountDownLatch latch;
        public LatchDemo(CountDownLatch latch) {
            this.latch = latch;
        }
        @Override
        public void run() {
            synchronized (this) {
                try {
                    for (int i = 0; i < 50000; i++) {
                        if (i % 2 == 0) {//50000以内的偶数
                            System.out.println(i);
                        }
                    }
                } finally {
                    latch.countDown();//每执行完一个就递减一个
                }
            }
        }
    }

创建线程的方式 (Callable Runnable)

相较于实现 Runnable 接口的方式,实现 Callable 接口类中的方法可以有返回值,并且可以抛出异常;
现在Callable接口和实现Runnable接口的区别就是,Callable带泛型,其call方法有返回值。使用的时候,需要用FutureTask来接收返回值。而且它也要等到线程执行完调用get方法才会执行,也可以用于闭锁操作。

Lock同步锁

Lock需要通过lock()方法上锁,通过unlock()方法释放锁。为了保证锁能释放,所有unlock方法一般放在finally中去执行。

代码参见: LockUserForCondition.java类

ReadWriteLock(读写锁)

我们在读数据的时候,可以多个线程同时读,不会出现问题,但是写数据的时候,如果多个线程同时写数据,那么到底是写入哪个线程的数据呢?所以,如果有两个线程,写写/读写需要互斥,读读不需要互斥。这个时候可以用读写锁

https://www.jianshu.com/p/1f19835e05c0
https://www.cnblogs.com/linkworld/p/7819270.html

线程池

使用线程时,需要new一个,用完了又要销毁,这样频繁的创建销毁也很耗资源,所以就提供了线程池。道理和连接池差不多,连接池是为了避免频繁的创建和释放连接,所以在连接池中就有一定数量的连接,要用时从连接池拿出,用完归还给连接池。线程池也一样。线程池中有一个线程队列,里面保存着所有等待状态的线程。下面来看一下用法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值