public class Thread_018 {
//默认创建的是非公平锁
Lock lock = new ReentrantLock();
//new ReentrantLock(true); 创建公平锁
//lock.newCondition(); 可以创建多个不同的等待队列
boolean locakState = false;
void m1(){
try {
lock.lock();//相当于 synchronized(this)
for (int i = 0; i < 10; i++) {
TimeUnit.SECONDS.sleep(1);
System.out.println(i);
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
void m2(){
try {
lock.lock();
System.out.println("m2 start...");
} finally {
lock.unlock();
}
}
void m3(){
try {
//tryLock 尝试获取锁不管锁定与否 程序都将继续执行
locakState = lock.tryLock(5, TimeUnit.SECONDS);
if(!locakState){
System.out.println("尝试5s获取锁都没获取到,进行对应的业务处理");
}else{
System.out.println("m3 start......");
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if(locakState){
lock.unlock();
}
}
}
public static void main(String[] args) {
Thread_018 t = new Thread_018();
new Thread(t::m1).start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(t::m2).start();
//new Thread(t::m3).start();
}
}
面试题:synchronized 与 ReentrantLock 的区别?
答:synchronized:系统自动加锁、解锁,不可以出现多个同的等待队列,默认进行四种锁状态的升级
ReentrantLock:需要手动加锁、解锁,可以出现多个不同的等待队列、cas实现
/**
* latch 就是 我规定一批线程的数量,下一批线程来了想要执行必须要等待
* 我这一批的latch倒数到0即所有线程执行完毕 门栓打开 下一批线程才可以进来
*/
public class Thread_023 {
public static void main(String[] args) {
countDown();
}
public static void countDown(){
Thread[] threads = new Thread[100];
CountDownLatch cdl = new CountDownLatch(threads.length);
for (int i = 0; i < 100; i++) {
threads[i] = new Thread(()->{
int result = 0;
for (int j = 0; j < 1000; j++) {
result ++;
}
//每个线程执行完毕之后需要对latch进行countDown操作
cdl.countDown();
},"t"+i);
}
for (int i = 0; i < 100; i++) {
threads[i].start();
}
try {
//门栓阻塞 需要倒数到0 才能继续执行
cdl.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("end");
}
}
/**
* 需要等待设定的所有资源到齐后栅栏打开,程序执行;随后栅栏重新起来再等待执行
*/
public class Thread_024 {
public static void main(String[] args) {
CyclicBarrier cyc = new CyclicBarrier(3,()-> System.out.println("资源填充完毕!准备发射!"));
for (int i = 0; i < 30; i++) {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
try {
cyc.await();
System.out.println(Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
},"t"+i).start();
}
}
}
/**
* 按照不同的阶段对线程进行执行 首先批量注册线程数量
* 在不同的阶段对线程是否向下运行进行不同操作
*/
public class Thread_025 {
static Random ran = new Random();
static Phaser phaser = new MarryPhaser();
public static void main(String[] args) {
//批量注册需要执行的线程数量
phaser.bulkRegister(7);
for (int i = 0; i < 5; i++) {
new Thread(new Person("p"+i)).start();
}
new Thread(new Person("新郎")).start();
new Thread(new Person("新娘")).start();
}
//继承Phaser 并对每个阶段进行不同操作
static class MarryPhaser extends Phaser{
@Override
protected boolean onAdvance(int phase, int registeredParties) {
switch (phase){
case 0:
System.out.println("所有人都到齐了 准备开饭!"+registeredParties);
return false;
case 1:
System.out.println("所有人都吃完了 准备离场!"+registeredParties);
return false;
case 2:
System.out.println("所有人都离场了 新郎新娘准备洞房!"+registeredParties);
return false;
case 3:
System.out.println("新郎新娘makeBaby!"+registeredParties);
return true;
default:
return true;
}
}
}
static class Person implements Runnable{
private String name;
public Person(String name) {
this.name = name;
}
@Override
public void run() {
arrive();//0阶段 按顺序排
eat();//1阶段
leave();//2阶段
makeBaby();//3阶段
}
void arrive() {
waitSeconds(ran.nextInt(10));
System.out.println(name + "到达婚礼现场!");
// 到达并等待向前 线程已经到达这个阶段并执行 等待其它线程完成一同向前
phaser.arriveAndAwaitAdvance();
}
void eat(){
waitSeconds(ran.nextInt(10));
System.out.println(name +"吃好喝好!");
phaser.arriveAndAwaitAdvance();
}
void leave(){
waitSeconds(ran.nextInt(10));
System.out.println(name +"吃完离开!");
phaser.arriveAndAwaitAdvance();
}
void makeBaby(){
waitSeconds(ran.nextInt(10));
if("新郎".equals(name) || "新娘".equals(name)){
waitSeconds(ran.nextInt(10));
System.out.println("make baby"+name);
phaser.arriveAndAwaitAdvance();
}else{
//根据不同的业务 对线程进行注销操作bulkRegister的数量会相应的跟随减少 促使其它线程可继续执行
phaser.arriveAndDeregister();
}
}
}
static void waitSeconds(int second){
try {
TimeUnit.SECONDS.sleep(second);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* 读写锁 保证读是共享锁 写是排他锁 保证读取的内容都是一样的
*/
public class Thread_026 {
static ReadWriteLock lock = new ReentrantReadWriteLock();
static Lock readLock = lock.readLock();
static Lock writeLock = lock.writeLock();
private static int value = 8;
static int read(Lock lock){
try {
lock.lock();
System.out.println("read over value is : "+value);
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
return value;
}
static void write(Lock lock,int v){
try {
lock.lock();
value = v;
System.out.println("write over value is : "+value);
} finally {
lock.unlock();
}
}
static void sleep(int sec){
try {
TimeUnit.SECONDS.sleep(sec);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Runnable read = () -> read(readLock);
Runnable write = () -> write(writeLock, new Random().nextInt(100));
for (int i = 0; i < 3; i++) {
new Thread(write).start();
}
for (int i = 0; i < 10; i++) {
new Thread(read).start();
}
}
}
/**
* Semaphore含义是限流
* 往Semaphore里面传一个数 --> 允许通过的数量
*/
public class Thread_027 {
//创建一个 允许一个permit通过的Semaphore 默认创建非公平锁
//new Semaphore(1,true); 创建公平锁
static Semaphore semaphore = new Semaphore(1);
static void read(){
try {
//阻塞方法 我如果获取不到permit我就阻塞再这里
semaphore.acquire();
System.out.println(Thread.currentThread().getName()+" is running");
sleep(5);
System.out.println(Thread.currentThread().getName()+" is over");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//返还通过许可 相当于释放锁
semaphore.release();
}
}
static void sleep(int sec){
try {
TimeUnit.SECONDS.sleep(sec);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Runnable read = () -> read();
for (int i = 1; i < 7; i++) {
// semaphore.drainPermits();
new Thread(read,"t"+i).start();
}
}
}
/**
* Exchanger 交换器 两个线程间通讯 交换数据
*/
public class Thread_029 {
static Exchanger exchanger = new Exchanger();
public static void main(String[] args) {
new Thread(()->{
int num = 10;
try {
num = Integer.parseInt(exchanger.exchange(num)+"");
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("t1 num is : " + num);
}).start();
new Thread(()->{
int num = 100;
try {
num = Integer.parseInt(exchanger.exchange(num)+"");
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("t2 num is : "+num);
}).start();
}
}
/**
* LockSupport 线程的唤醒和阻塞
*/
public class Thread_030 {
public static void main(String[] args) {
Thread t = new Thread(()->{
for (int i = 0; i < 10; i++) {
System.out.println(i);
if(i == 5){
//阻塞线程
LockSupport.park();
}
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
//唤醒线程 需要指定唤醒哪一个线程
//LockSupport.unpark(t);
}
}