并发中级第二篇
6. 多线程锁
6.1 8种锁
- 1.同一部手机,先短信还是先邮件
- 在两个线程之间加一个
Thread.sleep(100);
,可以达到先短信后邮件的目的。
- 在两个线程之间加一个
- 2.同一部手机,短信方法停4秒,先打印短信还是邮件(在解决1的情况下)
TimeUnit.SECONDS.sleep(4);
在短信方法里面(在phone类中的短信方法中),还是先打印短信
- 3.同一部手机,新增Hello方法,先打印短信还是hello
- 先Hello,停顿4秒,再打印短信
- 因为hello是普通的方法,不需要锁,当然也不需要等待,线程里有,直接执行就行
- 4.有两部手机,先打印短信还是先打印邮件(第一部手机调用短信,第二部手机调用邮件)
- 先邮件,后短信
- 5.两个静态同步方法,1部手机,先打印短信还是邮件
- getSMS
- getEmail
- 6.两个静态同步方法,2部手机,先打印短信还是邮件
- getSMS
- getEmail
- 7.1个静态同步方法,1个普通方法,1个手机,先打印短信还是邮件
- getEmail
- getSMS
- 8.1个静态同步方法,1个普通方法,2个手机,先打印短信还是邮件
- getEmail
- getSMS
package com.atguigu.sync;
import java.util.concurrent.TimeUnit;
class Machine {
public synchronized void sendSMS() throws Exception{
// TimeUnit.SECONDS.sleep(4);
System.out.println("----------sendSMS");
}
public synchronized void sendEmail() throws Exception{
System.out.println("----------sendEmail");
}
public void getHello(){
System.out.println("----------Hello");
}
}
public class Phone {
public static void main(String[] args) throws Exception {
Machine machine1 = new Machine();
Machine machine2 = new Machine();
new Thread(()->{
try {
machine1.sendSMS();
} catch (Exception e) {
e.printStackTrace();
}
},"AA").start();
Thread.sleep(10); //
new Thread(()->{
try {
machine2.sendEmail();
} catch (Exception e) {
e.printStackTrace();
}
},"BB").start();
}
}
6.2 公平锁和非公平锁
private Lock lock = new ReentrantLock(boolean); //在创建对象的类里面设置锁,多个线程是否公平由boolean决定
- 非公平锁:
- 线程饿死
- 效率高
- 公平锁
- 效率低
6.2 可重入锁
synchronized
(隐式)和ReentrantLock
(显式)都是可重入锁
6.3 死锁
- 两个或者两个以上线程在执行过程中,因为争夺资源而造成一种互相等待的现象,如果没有外力干涉,他们无法再继续执行下去。
- 死锁原因:
- 1.系统资源不足
- 2.线程推进顺序不合适
- 3.资源分配不当
7. Collable接口
-
Runnable接口方式和Thread类方式,无法返回线程结果。为了支持此功能,Java中提供了Callable接口。
-
Runnable接口和Callable接口:
- 是否抛出异常
- 是否有返回值
- 实现方法名称不同。一个是call方法,一个是run方法。
package com.atguigu.sync;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
//实现Runnable接口
class MyThread1 implements Runnable{
@Override
public void run() {
}
}
class MyThread2 implements Callable{
@Override
public Integer call() throws Exception {
return 200;
}
}
public class Demo1 {
public static void main(String[] args) {
//Runnnable接口创建线程
new Thread(new MyThread1(),"AA").start();
//Callable
FutureTask<Integer> futureTask = new FutureTask<Integer>(new MyThread2());
//lam表达式
FutureTask<Integer> futureTask1 = new FutureTask<Integer>(()->{
return 1024;
});
}
}
8. JUC强大的辅助类
8.1 减少计数CountDownLatch
8.2 循环栅栏CyclicBarrier
8.3 信号灯Semaphore
9. ReentrantReadWriteLock读写锁
- 悲观锁 和 乐观锁
- 表锁 和 行锁
- 读锁 和 写锁
- 读锁:共享锁
- 写锁:独占锁