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("打电话");
}
}

浙公网安备 33010602011771号