关于8锁需要弄明白的就是锁的是谁,其他线程能不能抢占到锁?
1.1-2锁
- 标准访问有ab两个线程,请问先打印邮件还是短信?
- sendEmail 方法中加入暂停3s 请问是先打印邮件还是短信?
package com.sol.lock_8;
import java.util.concurrent.TimeUnit;
/**
* 1.标志情况下,两个线程先打印,发短信? 打电话?
* 2.sendSms延迟4秒,两个线程先打印,发短信? 打电话?
*/
public class Lock_1To2 {
public static void main(String[] args) throws InterruptedException {
Phone phone = new Phone();
//发短信
new Thread(()->{
try {
phone.sendSms();
} catch (InterruptedException e) {
e.printStackTrace();
}
},"发短信").start();
//延时
TimeUnit.SECONDS.sleep(1);
//打电话
new Thread(()->{
phone.call();
},"打电话").start();
}
}
class Phone{
//synchronized 锁的对象是方法的调用者
//两个方法使用的是同一个锁,哪个先拿到哪个先执行
public synchronized void sendSms() throws InterruptedException {
TimeUnit.SECONDS.sleep(4);
System.out.println("发短信");
}
public synchronized void call(){
System.out.println("打电话");
}
}
结论 :一个对象里面如果有多个synchronized方法,某一时刻内只能有一个线程去访问这些synchronized方法,锁的是当前对象this,被锁定后,其他线程都不能进入到当前对象的其他synchronized方法
2.3-4锁
- 有一部手机 一个普通的hello方法,一个睡眠3s邮件方法,请问先打印邮件还是 hello方法
- 有两部手机,一个普通的hello方法,一个睡眠3s邮件方法,请问先打印邮件还是 hello方法
package com.sol.lock_8;
import java.util.concurrent.TimeUnit;
/**
* 3.静态方法,普通方法 打电话?发短信?
* 4.不同对象 打电话?发短信?
*/
public class Lock_3To4 {
public static void main(String[] args) throws InterruptedException {
Phone2 phone2 = new Phone2();
Phone2 phone3 = new Phone2();
//发短信
new Thread(()->{
try {
phone2.sendSms();
} catch (InterruptedException e) {
e.printStackTrace();
}
},"发短信").start();
//延时
TimeUnit.SECONDS.sleep(1);
//打电话
new Thread(()->{
phone3.call();
},"打电话").start();
}
}
class Phone2{
//synchronized 锁的对象是方法的调用者
//两个方法使用的是同一个锁,哪个先拿到哪个先执行
public synchronized void sendSms() throws InterruptedException {
TimeUnit.SECONDS.sleep(3);
System.out.println("发短信");
}
public synchronized void call(){
System.out.println("打电话");
}
//不是同步方法,不受锁的影响
public void hello(){
System.out.println("hello");
}
}
结论 :1.普通方法与同步锁无关直接执行
2.换成两个对象不是同一把锁,各锁各的this 对象锁
3.5-6锁
- 静态同步方法,同一对象,发短信? 打电话?
- 静态同步方法,不同对象,两个线程先打印,发短信? 打电话?
package com.sol.lock_8;
import java.util.concurrent.TimeUnit;
/**
* 5.静态同步方法,同一对象,发短信? 打电话?
* 6.静态同步方法,不同对象,两个线程先打印,发短信? 打电话?
*/
public class Lock_5To6 {
public static void main(String[] args) throws InterruptedException {
Phone3 phone1 = new Phone3();
Phone3 phone2 = new Phone3();
//发短信
new Thread(()->{
try {
phone1.sendSms();
} catch (InterruptedException e) {
e.printStackTrace();
}
},"发短信").start();
//延时
TimeUnit.SECONDS.sleep(1);
//打电话
new Thread(()->{
phone2.call();
},"打电话").start();
}
}
class Phone3{
//类一加载就有了!锁的是Class
//synchronized 锁的对象是方法的调用者
//两个方法使用的是同一个锁,哪个先拿到哪个先执行
public static synchronized void sendSms() throws InterruptedException {
TimeUnit.SECONDS.sleep(3);
System.out.println("发短信");
}
public static synchronized void call(){
System.out.println("打电话");
}
}
结论 :对于静态同步方法锁的是当前类的Class对象,同一把类锁
4.7-8锁
- 静态同步方法和同步方法,有1部手机,请问先打印邮件还是短信?
- 静态同步方法和同步方法,有2部手机,清问先打印邮件还是短信?
package com.sol.lock_8;
/**
* 7.静态同步方法和同步方法 ,同一对象 发短信?打电话?
* 8.静态同步方法和同步方法 ,不同对象 发短信?打电话?
*/
import java.util.concurrent.TimeUnit;
public class Lock_7To8 {
public static void main(String[] args) throws InterruptedException {
Phone4 phone1 = new Phone4();
Phone4 phone2 = new Phone4();
//发短信
new Thread(()->{
phone1.sendSms();
},"发短信").start();
//延时
TimeUnit.SECONDS.sleep(1);
//打电话
new Thread(()->{
phone2.call();
},"打电话").start();
}
}
class Phone4{
//不同的锁,谁先拿到谁执行
public static synchronized void sendSms() {
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("发短信");
}
public synchronized void call(){
System.out.println("打电话");
}
}
> 结论 :静态同步方法和同步方法 一个锁的Class 一个锁的this 不同的锁,谁先拿到谁执行