8锁的详解

8种不同的锁情况,分别由8个例子讲解

-------------------------------锁一----------------------------------
import java.util.concurrent.TimeUnit;

/*
lock1:两个同步方法(发短信、打电话),创建一个对象,两个线程,第一个线程调用该对象的发短信方法,第二个线程调用该对象的打电话方法
结果:发短信->打电话
解答:同步方法锁的是方法的调用者,也就是对象,两条线程方法的调用者是同个对象,所以两条线程谁先拿到这个对象的锁,就先执行。
*/
public class TestLock1 {
public static void main(String[] args) throws InterruptedException {
TelPhone phone = new TelPhone();
new Thread(()->{
phone.sendSms();
}, "A").start();

TimeUnit.SECONDS.sleep(1);

new Thread(()->{
phone.call();
}, "B").start();
}
}

class TelPhone{
//发短信
public synchronized void sendSms(){
System.out.println("发短信");
}

public synchronized void call(){
System.out.println("打电话");
}
}


-------------------------------锁二----------------------------------
import java.util.concurrent.TimeUnit;

/*
lock2:两个同步方法(发短信(延迟2秒执行)、打电话),创建一个对象,两个线程,
  第一个线程调用该对象的发短信方法,第二个线程调用该对象的打电话方法
结果:发短信->打电话
解答:同lock1
*/
public class TestLock2 {
public static void main(String[] args) throws InterruptedException {
TelPhone2 phone = new TelPhone2();
new Thread(()->{
phone.sendSms();
}, "A").start();

TimeUnit.SECONDS.sleep(1);

new Thread(()->{
phone.call();
}, "B").start();
}
}

class TelPhone2{
//发短信
public synchronized void sendSms(){
//休眠2秒
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}

public synchronized void call(){
System.out.println("打电话");
}
}

-------------------------------锁三----------------------------------
import java.util.concurrent.TimeUnit;

/*
lock3:增加一个普通方法
结果:hello->发短信
解答:hello是普通方法,没有锁
*/
public class TestLock3 {
public static void main(String[] args) throws InterruptedException {
TelPhone3 phone = new TelPhone3();
new Thread(()->{
phone.sendSms();
}, "A").start();

TimeUnit.SECONDS.sleep(1);

new Thread(()->{
phone.hello();
}, "B").start();
}
}

class TelPhone3{
//发短信
public synchronized void sendSms(){
//休眠2秒
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}

public synchronized void call(){
System.out.println("打电话");
}

public void hello(){
System.out.println("hello");
}
}

-------------------------------锁四----------------------------------
import java.util.concurrent.TimeUnit;

/*
lock4:两个同步方法(发短信、打电话),创建两个对象,两个线程,第一个线程调用第一个对象的发短信方法,第二个线程调用第二个对象的打电话方法
结果:打电话->发短信
解答:同步方法锁的是方法的调用者,也就是对象,但两条线程方法的调用者是两个对象,两个对象分别有各自的锁,所以互不影响。
*/
public class TestLock4 {
public static void main(String[] args) throws InterruptedException {
TelPhone4 phone1 = new TelPhone4();
TelPhone4 phone2 = new TelPhone4();
new Thread(()->{
phone1.sendSms();
}, "A").start();

TimeUnit.SECONDS.sleep(1);

new Thread(()->{
phone2.call();
}, "B").start();
}
}

class TelPhone4{
//发短信
public synchronized void sendSms(){
//休眠2秒
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}

public synchronized void call(){
System.out.println("打电话");
}
}
-------------------------------锁五----------------------------------
/*
lock5:两个静态的同步方法(发短信、打电话),创建一个对象,两个线程,第一个线程调用该对象的发短信方法,第二个线程调用该对象的打电话方法
结果:发短信->打电话
解答:static,类一加载就有了,锁的是Class。
*/
public class TestLock5 {
public static void main(String[] args) throws InterruptedException {
TelPhone5 phone = new TelPhone5();
new Thread(()->{
phone.sendSms();
}, "A").start();

TimeUnit.SECONDS.sleep(1);

new Thread(()->{
phone.call();
}, "B").start();
}
}

class TelPhone5{
//发短信
public static synchronized void sendSms(){
//休眠2秒
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}

public static synchronized void call(){
System.out.println("打电话");
}
}
-------------------------------锁六----------------------------------
/*
lock6:两个静态的同步方法(发短信、打电话),创建两个对象,两个线程,第一个线程调用第一个对象的发短信方法,第二个线程调用第二个对象的打电话方法
结果:发短信->打电话
解答:两个对象的Class模板只有一个,static锁的是Class
*/
public class TestLock6 {
public static void main(String[] args) throws InterruptedException {
TelPhone6 phone1 = new TelPhone6();
TelPhone6 phone2 = new TelPhone6();
new Thread(()->{
phone1.sendSms();
}, "A").start();

TimeUnit.SECONDS.sleep(1);

new Thread(()->{
phone2.call();
}, "B").start();
}
}

class TelPhone6{
//发短信
public static synchronized void sendSms(){
//休眠2秒
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}

public static synchronized void call(){
System.out.println("打电话");
}
}
-------------------------------锁七----------------------------------
import java.util.concurrent.TimeUnit;

/*
lock7:一个静态的同步方法(发短信)一个普通的同步方法(打电话),创建一个对象,两个线程,第一个线程调用该对象的发短信方法,第二个线程调用该对象的打电话方法
结果:打电话->发短信
解答:发短信(静态同步方法)锁的是Class模板,打电话(普通同步方法)锁的是方法,两者是不同的锁
*/
public class TestLock7 {
public static void main(String[] args) throws InterruptedException {
TelPhone7 phone = new TelPhone7();
new Thread(()->{
phone.sendSms();
}, "A").start();

TimeUnit.SECONDS.sleep(1);

new Thread(()->{
phone.call();
}, "B").start();
}
}

class TelPhone7{
//发短信
public static synchronized void sendSms(){
//休眠2秒
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}

public synchronized void call(){
System.out.println("打电话");
}
}
-------------------------------锁八----------------------------------
import java.util.concurrent.TimeUnit;

/*
lock8:一个静态的同步方法(发短信)一个普通的同步方法(打电话),创建两个对象,两个线程,第一个线程调用第一个对象的发短信方法,第二个线程调用第二个对象的打电话方法
结果:打电话->发短信
解答:发短信对象锁的是Class模板,打电话对象锁的是方法,不同的锁
*/
public class TestLock8 {
public static void main(String[] args) throws InterruptedException {
TelPhone8 phone1 = new TelPhone8();
TelPhone8 phone2 = new TelPhone8();
new Thread(()->{
phone1.sendSms();
}, "A").start();

TimeUnit.SECONDS.sleep(1);

new Thread(()->{
phone2.call();
}, "B").start();
}
}

class TelPhone8{
//发短信
public static synchronized void sendSms(){
//休眠2秒
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("发短信");
}

public synchronized void call(){
System.out.println("打电话");
}
}


posted @ 2021-08-06 15:34  gdstcymc  阅读(197)  评论(0)    收藏  举报