多线程随笔-1

CAS(无锁优化)

伪代码解释

cas(V,Expected,NewValue) {
	if V==E
		V == NewValue
	otherwise try again or fail
}

V(当前值),Expected(期望值),NewValue(新值)

当v等于e时,将n赋予v,否则进行自旋操作

ABA问题

在进行cas时,有线程更改了v,之后又更改回来,让程序以为没发生改变

解决方案

设立版本号,在cas时加上版本号比较,atmic包中存在版本号的类

ReentrantLock

Lock lock = new ReentrantLock();
try {
	lock.lock(); 
	......
} catch (InterruptedException e) {
	e.printStackTrace();
} finally {
	lock.unlock();
}

ReentrantLock需要手动解锁,synchronized自动解锁,两把锁都是可重入锁
ReentrantLock可以替代synchronized,ReentrantLock还拥有synchronized不存在的方法

tryLock()

tryLock()可以设置超时时间,当线程未在指定时间内获得锁便立刻返回false,反之返回true。

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();
}

lockInterruptibly()

ReentrantLock.lockInterruptibly允许在等待时由其它线程调用等待线程的Thread.interrupt方法来中断等待线程的等待而直接返回,这时不用获取锁,而会抛出一个InterruptedException。

ReentrantLock(true)

指定ReentrantLock为公平锁,即线程的执行是按照FIFO的顺序执行的(并不绝对)

CountDownLatch

通过计数控制锁的锁定和开启
CountDownLatch是原子类

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

监听等待在CyclicBarrier上的线程数量,一旦达到指定的数量,就执行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

分段执行各个线程(类似先异步后同步)

ReadWriteLock

共享锁/写锁 : readWriteLock.readLock()
排它锁/读锁/互斥锁/独占锁 : readWriteLock.writeLock()

static Lock lock = new ReentrantLock();
private static int value;

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

public static void read(Lock lock) {
    try {
        lock.lock();
        Thread.sleep(1000);
        System.out.println("read over!");
        //模拟读取操作
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        lock.unlock();
    }
}

public static void write(Lock lock, int v) {
    try {
        lock.lock();
        Thread.sleep(1000);
        value = v;
        System.out.println("write over!");
        //模拟写操作
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        lock.unlock();
    }
}

public static void main(String[] args) {
    //Runnable readR = ()-> read(lock);
    Runnable readR = ()-> read(readLock);

    //Runnable writeR = ()->write(lock, new Random().nextInt());
    Runnable writeR = ()->write(writeLock, new Random().nextInt());

    for(int i=0; i<18; i++) new Thread(readR).start();
    for(int i=0; i<2; i++) new Thread(writeR).start();
}

Semaphore

semaphore的作用是限流,可以指定同时运行线程的个数

Semaphore s = new Semaphore(1);
。。。
// acquire的作用是线程获取锁,只有获取到锁的线程才能继续执行
s.acquire();
。。。

Exchanger

用于交换两个线程的数据,需要同时调用exchanger.exchange()方法

线程1调用exchanger.exchange()方法,Exchanger阻塞线程1
线程2调用exchanger.exchange()方法,Exchanger阻塞线程2
交换数值
线程1和线程2继续执行

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值