多线程相关类(锁常用类) ReentrantLock, ReadWriteLock读写锁等

多线程相关类(锁常用类) ReentrantLock, ReadWriteLock读写锁等,第1张

线程相关类(锁常用类) ReentrantLock, ReadWriteLock读写锁等 Synchronized之外的锁

Synchronized: 系统锁 重量级锁
涉及内容,锁优化,自旋锁(轻量级锁),锁升级

ReentrantLock锁

也是可重入锁
ReentrantLock 可以 替代 Synchronized.
使用方法
try中lock(), finally中unlock()

ReentrantLock和Synchronized的区别 黄色就是ReentrantLock的优势
    ReentrantLock是手动加锁解锁,Synchronized是自动的。比较灵活synchronized如果拿不到锁就阻塞wait,但ReentrantLock有tryLock方法,可以尝试拿 锁。
    使用方法
    boolean locked = false;
    		
    try {
    	locked = lock.tryLock(5, TimeUnit.SECONDS);
    	System.out.println("m2 ..." + locked);
    } catch (InterruptedException e) {
    	e.printStackTrace();
    } finally {
    	if(locked) lock.unlock();
    }
    
    注意:这里tryLock() 拿不到锁不是进异常ReentrantLock还可以设置为公平锁
    ReentrantLock lock=new ReentrantLock(true);
    这里默认参数:false(非公平)
    公平锁就是有一个线程等待的队列,非公平锁上来直接抢,不管有没有队列,公平就是判断有没有队列,有队列就排队。
CountDownLatch

Latch闩锁 countDouwnLatch 倒数的门锁

就是线程执行完了

使用方法
Thread[] threads = new Thread[100];
CountDownLatch latch = new CountDownLatch(threads.length);

for(int i = 0; i < threads.length; i++) {
	threads[i] = new Thread(() -> {
		int result = 0;
		for(int j = 0; j < 10000; j++)
			result += j;
		latch.countDown();
	});
}

for(int i = 0; i < threads.length; i++) {
	threads[i].start();
}

try {
	latch.await();
} catch (InterruptedException e) {
	e.printStackTrace();
}
CyclicBarrier

Barrier 栅栏 CyclicBarrier 循环栅栏

new CyclicBarrier()参数中的第一个参数就是线程数量,就是什么时候线程达到这个数量,就继续执行

CyclicBarrier 和 CountDownLatch的区别:
CountDownLatch是执行完就减一(可以是一个线程多次执行),CyclicBarrier是当线程数达到规定数量时才执行下·

使用方法:

CyclicBarrier barrier = new CyclicBarrier(20, new Runnable() {
	@Override
	  public void run() {
	      System.out.println("满人,发车");
	  }
});

for(int i=0; i<100; i++) {
	new Thread(()->{
	    try {
	        barrier.await();
	    } catch (InterruptedException e) {
	        e.printStackTrace();
	    } catch (BrokenBarrierException e) {
	        e.printStackTrace();
	    }
	}).start();    
}
Phaser

Phase 阶段
类似于一个又一个的barrier
可以解决遗传算法
使用方法:
MarriagePhaser phaser = new MarriagePhaser();
phaser.bulkRegister([中间是自己定义的一共多少个线程]);
phaser.arriveAndDeregister();
phaser.arriveAndAwaitAdvance();
类需要继承Phaser然后重写onAdvance() 方法

ReadWriteLock

顾名思义:读写锁
可以锁读,可以锁写

往死了重要!
共享锁:
共享,就是多个人可以共享一把锁,翻译成人话就是有这个锁的就是自家人,就可以执行。其中读锁就是共享锁,意思就是不同线程读的时候用的锁就是同一把锁,就是读线程拿到锁的时候只要是读线程就可以访问。
排他锁:
写锁就是排他锁,就是自己一个人用。其他写线程和读线程都不能用。(自私)

问:为什么不只给写上锁?
会出现脏读现象

使用方法:

static int number = 123;

    static ReentrantLock lock = new ReentrantLock();

    static ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    static Lock readLock = readWriteLock.readLock();
    static Lock writeLock = readWriteLock.writeLock();

    private static void readMethod(Lock lock) {
        try {
            lock.lock();
            Thread.sleep(500);
            System.out.println("read Method! ");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    private static void writeMethod(Lock lock, int n) {
        try {
            lock.lock();
            number = n;
            Thread.sleep(500);
            System.out.println("write Method! ");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        T10_Exercise t = new T10_Exercise();
        

        for (int i = 0; i < 18; i++) {
            new Thread(() -> readMethod(readLock)).start();
        }
        for (int i = 0; i < 2; i++) {
            new Thread(() -> writeMethod(writeLock, 888)).start();
        }
    }
Semaphore

semaphore 信号

使用:
Semaphore s = new Semaphore(permits:2);//也可以设置为公平 true
s.acquire(); //拿到信号量,信号量数据–,减到为零就不能获取了
s.release(); //释放信号量,信号量数据++

使用场景:限流
小问题:
semaphore中permits是可以同时运行的线程一共有多少个,但有多少个线程在线程池中不管。

Exchanger

两个线程中交换数据使用(不同线程中的通信)

static Exchanger exchanger = new Exchanger<>();

public static void main(String[] args) {
   new Thread(()->{
       String s = "T1";
       try {
           s = exchanger.exchange(s);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
       System.out.println(Thread.currentThread().getName() + " " + s);

   }, "t1").start();


   new Thread(()->{
       String s = "T2";
       try {
           s = exchanger.exchange(s);
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
       System.out.println(Thread.currentThread().getName() + " " + s);

   }, "t2").start();
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5708308.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-18
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存