8锁现象,实际对应的就是8个问题 掌握了这8个问题后:可以清楚判断锁的是谁
1.多个线程使用同一把锁
import java.util.concurrent.TimeUnit;
public class lock1 {
public static void main(String[] args) {
Phone phone = new Phone();
new Thread(()->{
phone.sendemail();
},"A").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
phone.call();
},"B").start();
}
}
class Phone{
public synchronized void sendemail(){
System.out.println("sendemail");
}
public synchronized void call(){
System.out.println("call");
}
}
此时synchronized 锁的对象是方法的调用者(phone),这两个方法共用同一个锁,谁先拿到谁执行
由执行sendemail的线程先拿到锁,所以先执行
2.多个线程使用同一把锁,其中某个线程里面还有阻塞
import java.util.concurrent.TimeUnit;
public class lock2 {
public static void main(String[] args) {
Phone2 phone = new Phone2();
new Thread(()->{
phone.sendemail();
},"A").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
phone.hello();
},"B").start();
}
}
class Phone2{
public synchronized void sendemail(){
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("sendemail");
}
public synchronized void call(){
System.out.println("call");
}
}
先拿到锁的先执行,即使在某方法中设置了阻塞
- phone对象,就是方法的调用者,它可以打电话和发短信
- 现在有两个人线程A 和 线程B,他们一个想打电话,一个想发短信
- 线程A,先拿到锁,抱着锁睡了4秒
- 线程B肯定拿不到锁,需要等待线程A执行完
3.多个线程有锁与没锁
import java.util.concurrent.TimeUnit;
public class lock3 {
public static void main(String[] args) {
Phone3 phone1 = new Phone3();
new Thread(()->{
phone1.sendemail();
},"A").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
phone1.hello();
},"B").start();
}
}
class Phone3{
public synchronized void sendemail(){
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("sendemail");
}
public void hello(){
System.out.println("hello");
}
}
有的线程有锁,有的线程没锁,两者之间不存在竞争同一把锁的情况,先后执行顺序是随机的
但是由于A线程休眠了一秒,所以会先执行B线程
4.多个线程使用多把锁
import java.util.concurrent.TimeUnit;
public class lock4 {
public static void main(String[] args) {
Phone4 phone1 = new Phone4();
Phone4 phone2 = new Phone4();
new Thread(()->{
phone1.sendemail();
},"A").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
phone2.call();
},"B").start();
}
}
class Phone4{
public synchronized void sendemail(){
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("sendemail");
}
public synchronized void call(){
System.out.println("call");
}
}
调用者不同,它们之间用的不是同一个锁,A获取锁后休眠一秒,B先出现执行结果
5.锁class模板
import java.util.concurrent.TimeUnit;
public class lock5 {
public static void main(String[] args) {
new Thread(()->{
Phone5.sendemail();
},"A").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
Phone5.call();
},"B").start();
}
}
class Phone5{
public static synchronized void sendemail(){
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("sendemail");
}
public static synchronized void call(){
System.out.println("call");
}
}
因为锁的是class模板,而这个模板是唯一的一个,所以无论几个对象,使用的锁都是一样
6.锁方法的调用者和锁class模板
import java.util.concurrent.TimeUnit;
public class lock6 {
public static void main(String[] args) {
Phone6 people = new Phone6();
new Thread(()->{
Phone6.sendemail();
},"A").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
people.call();
},"B").start();
}
}
class Phone6{
public static synchronized void sendemail(){
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("sendemail");
}
public synchronized void call(){
System.out.println("call");
}
}
两个锁的东西是不同,一个锁的是class模板,一个锁的是方法调用者,两个都是互不影响