1.Lock 锁
synchronized修饰跟lock效果一样
Lock lock = new ReentrantLock();
new Thread(new Runnable() {
@Override
public void run() {
lock.lock();
try {
System.out.println("Thread++++等待中");
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}).start();
lock.lock();
System.out.println("等待中");
Thread.sleep(3000);
lock.unlock();
System.out.println("ending+++++++++===");
2.读写锁
分读锁和写锁 多个读锁不互斥,对锁与血锁互斥,写锁与写锁互斥
下面是ReentrantReadWriteLock注释中的demo实现一个简单的缓存机制
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
System.out.println(processCachedData());
}
}
private static Object data;
private static volatile boolean cacheValid;
private final static ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
public static Object processCachedData() {
rwl.readLock().lock();
if (!cacheValid) {
// Must release read lock before acquiring write lock
rwl.readLock().unlock();
rwl.writeLock().lock();
try {
// Recheck state because another thread might have
// acquired write lock and changed state before we did.
if (!cacheValid) {
data = System.currentTimeMillis();
cacheValid = true;
}
// Downgrade by acquiring read lock before releasing write lock
rwl.readLock().lock();
} finally {
rwl.writeLock().unlock(); // Unlock write, still hold read
}
}
try {
return data;
} finally {
rwl.readLock().unlock();
}
}
3.Condition
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
condition.await();相当于this.wait()
condition.signal();相当于 this.notify()
4.Semaphore
只允许3个线程同时执行
{
ExecutorService executorService = Executors.newCachedThreadPool();
Semaphore s = new Semaphore(3);
for (int i = 0; i < 10; i++) {
Runnable runnable = new Runnable() {
@Override
public void run() {
try {
s.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "::进入,当前使用线程为:" + (3 - s.availablePermits()));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
s.release();
System.out.println(Thread.currentThread().getName() + "::离开,当前使用线程为:" + (3 - s.availablePermits()));
}
};
executorService.execute(runnable);
}
}
结果:
pool-1-thread-2::进入,当前使用线程为:3
pool-1-thread-3::进入,当前使用线程为:3
pool-1-thread-1::进入,当前使用线程为:3
pool-1-thread-2::离开,当前使用线程为:0
pool-1-thread-3::离开,当前使用线程为:0
pool-1-thread-6::进入,当前使用线程为:2
pool-1-thread-4::进入,当前使用线程为:1
pool-1-thread-1::离开,当前使用线程为:0
pool-1-thread-5::进入,当前使用线程为:3
pool-1-thread-8::进入,当前使用线程为:2
pool-1-thread-4::离开,当前使用线程为:2
pool-1-thread-7::进入,当前使用线程为:3
pool-1-thread-6::离开,当前使用线程为:2
pool-1-thread-9::进入,当前使用线程为:2
pool-1-thread-5::离开,当前使用线程为:2
pool-1-thread-7::离开,当前使用线程为:2
pool-1-thread-8::离开,当前使用线程为:1
pool-1-thread-9::离开,当前使用线程为:1
pool-1-thread-10::进入,当前使用线程为:1
pool-1-thread-10::离开,当前使用线程为:0
5.CyclicBarrier
cb.await();等待控制访问线程数,当等待数为3时,继续往下走
{
ExecutorService service = Executors.newCachedThreadPool();
final CyclicBarrier cb = new CyclicBarrier(3);
for (int i = 0; i < 3; i++) {
Runnable runnable = new Runnable() {
@Override
public void run() {
try {
Thread.sleep((long) (Math.random() * 10000));
System.out.println("线程" + Thread.currentThread().getName() + ":" + cb.getNumberWaiting());
cb.await();
System.out.println("全到");
Thread.sleep((long) (Math.random() * 10000));
System.out.println("线程" + Thread.currentThread().getName() + ":" + cb.getNumberWaiting());
cb.await();
System.out.println("全到");
Thread.sleep((long) (Math.random() * 10000));
System.out.println("线程" + Thread.currentThread().getName() + ":" + cb.getNumberWaiting());
cb.await();
System.out.println("全到");
} catch (Exception e) {
e.printStackTrace();
}
}
};
service.execute(runnable);
}
}
输出结果:
线程pool-1-thread-1:0
线程pool-1-thread-3:1
线程pool-1-thread-2:2
线程pool-1-thread-2:0
线程pool-1-thread-1:1
线程pool-1-thread-3:2
线程pool-1-thread-1:0
线程pool-1-thread-3:1
线程pool-1-thread-2:2
6.CountDownLatch
当设置计数为1时,可使用countDown可以指定唤醒 那个对应线程
demo 实现a线程执行完,在执行b线程,b线程执行完 在执行c线程 依次往复50次
public class CountdownLatchTest {
/**
* new一个新对象将设置数值 计数器为0时,则所有等待或单个等待开始执行
*
* @param args
*/
public static void main(String[] args) {
// CountDownLatch cd1 = new CountDownLatch(1);
// CountDownLatch cd2 = new CountDownLatch(1);
// CountDownLatch cd3 = new CountDownLatch(1);
Test2 test2 = new Test2();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 20; i++) {
test2.sub1(i);
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 20; i++) {
test2.sub2(i);
}
}
}).start();
for (int i = 0; i < 20; i++) {
test2.sub3(i);
}
}
}
7.Exchanger
实现线程之间的数据互换,如果当一个线程正在交换,无交换对象 则等待下一个线程 完成交换
{
Exchanger e = new Exchanger();
new Thread(new Runnable() {
@Override
public void run() {
String t1 = "线程1";
try {
Thread.sleep(5000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
try {
String b = (String) e.exchange(t1);
System.out.println("线程1交换结果:" + b);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}).start();
String t2 = "线程2";
String b1 = (String) e.exchange(t2);
System.out.println("线程2交换结果:" + b1);
}
输出结果:
等待5s后 输出结果
线程1交换结果:线程2
线程2交换结果:线程1
网友评论