static和synchronized
2个线程模拟手机发邮件和发短信功能
八锁
- 标准访问
2
个线程 一部手机资源类 - 发邮件睡眠
4
秒 - 新增
sayHello
方法 - 两部手机资源类
2
个静态同步方法 一部手机2
个静态同步方法 两部部手机1
个静态同步方法 一个普通同步方法 一部手机1
个静态同步方法 一个普通同步方法 两部部手机
场景一
标准访问 2
个线程 一部手机资源类
package com.zbiti.juc;
import java.util.concurrent.TimeUnit;
public class LockDemo {
public static void main(String[] args) throws InterruptedException {
Phone phone = new Phone();
new Thread(() -> {
phone.sendEmail();
}, "AA").start();
TimeUnit.SECONDS.sleep(2);
new Thread(() -> {
phone.sendSMS();
}, "BB").start();
}
}
//手机资源类,带发邮件、发短信功能
class Phone {
//发邮件
synchronized void sendEmail() {
System.out.println("sendEmail----->");
}
//发短信
synchronized void sendSMS() {
System.out.println("sendSMS------->");
}
}
结果
场景二
发邮件睡眠4
秒
package com.zbiti.juc;
import java.util.concurrent.TimeUnit;
public class LockDemo {
public static void main(String[] args) throws InterruptedException {
Phone phone = new Phone();
new Thread(() -> {
phone.sendEmail();
}, "AA").start();
TimeUnit.SECONDS.sleep(2);
new Thread(() -> {
phone.sendSMS();
}, "BB").start();
}
}
//手机资源类,带发邮件、发短信功能
class Phone {
//发邮件
synchronized void sendEmail() {
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("sendEmail----->");
}
//发短信
synchronized void sendSMS() {
System.out.println("sendSMS------->");
}
}
结果
synchronized
锁的当前对象,一个对象里面如果有多个synchronized
方法,某一个时刻内,只要一个线程去调用其中的一个synchronized
方法了,其它线程都只能等待,换句话说,某一个时刻内,只能有唯一一个线程去访问这些synchronized
方法
场景三
新增sayHello
方法
package com.zbiti.juc;
import java.util.concurrent.TimeUnit;
public class LockDemo {
public static void main(String[] args) throws InterruptedException {
Phone phone = new Phone();
new Thread(() -> {
phone.sendEmail();
}, "AA").start();
TimeUnit.SECONDS.sleep(2);
new Thread(() -> {
phone.sayHello();
}, "BB").start();
}
}
//手机资源类,带发邮件、发短信功能
class Phone {
//发邮件
synchronized void sendEmail() {
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("sendEmail----->");
}
//发短信
synchronized void sendSMS() {
System.out.println("sendSMS------->");
}
void sayHello(){
System.out.println("sayHello------>");
}
}
结果
加个普通方法后发现和同步方法无关
场景四
两部手机资源类
package com.zbiti.juc;
import java.util.concurrent.TimeUnit;
public class LockDemo {
public static void main(String[] args) throws InterruptedException {
Phone phone = new Phone();
Phone phone2 = new Phone();
new Thread(() -> {
phone.sendEmail();
}, "AA").start();
TimeUnit.SECONDS.sleep(2);
new Thread(() -> {
phone2.sendSMS();
}, "BB").start();
}
}
//手机资源类,带发邮件、发短信功能
class Phone {
//发邮件
synchronized void sendEmail() {
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("sendEmail----->");
}
//发短信
synchronized void sendSMS() {
System.out.println("sendSMS------->");
}
void sayHello(){
System.out.println("sayHello------>");
}
}
结果
换成两个对象后,不是同一把锁,情况立刻发生了变化,所有的非静态同步方法用的都是同一把锁,即实例对象本身
场景五
2
个静态同步方法 一部手机
package com.zbiti.juc;
import java.util.concurrent.TimeUnit;
public class LockDemo {
public static void main(String[] args) throws InterruptedException {
Phone phone = new Phone();
Phone phone2 = new Phone();
new Thread(() -> {
phone.sendEmail();
}, "AA").start();
TimeUnit.SECONDS.sleep(2);
new Thread(() -> {
phone.sendSMS();
// phone2.sendSMS();
}, "BB").start();
}
}
//手机资源类,带发邮件、发短信功能
class Phone {
//发邮件
static synchronized void sendEmail() {
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("sendEmail----->");
}
//发短信
static synchronized void sendSMS() {
System.out.println("sendSMS------->");
}
void sayHello() {
System.out.println("sayHello------>");
}
}
结果
synchronized
实现同步的基础,java
中的每一个对象都可以作为锁,具体表现以下3种形式
- 对于普通同步方法,锁是当前实例对象
- 对于同步方法块,锁是
synchronized
括号里配置的对象 - 对于静态同步方法,锁是当前类的
Class
对象
场景六
2
个静态同步方法 两部部手机
package com.zbiti.juc;
import java.util.concurrent.TimeUnit;
public class LockDemo {
public static void main(String[] args) throws InterruptedException {
Phone phone = new Phone();
Phone phone2 = new Phone();
new Thread(() -> {
phone.sendEmail();
}, "AA").start();
TimeUnit.SECONDS.sleep(2);
new Thread(() -> {
// phone.sendSMS();
phone2.sendSMS();
}, "BB").start();
}
}
//手机资源类,带发邮件、发短信功能
class Phone {
//发邮件
static synchronized void sendEmail() {
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("sendEmail----->");
}
//发短信
static synchronized void sendSMS() {
System.out.println("sendSMS------->");
}
void sayHello() {
System.out.println("sayHello------>");
}
}
结果
场景七
1
个静态同步方法 一个普通同步方法 一部手机
package com.zbiti.juc;
import java.util.concurrent.TimeUnit;
public class LockDemo {
public static void main(String[] args) throws InterruptedException {
Phone phone = new Phone();
Phone phone2 = new Phone();
new Thread(() -> {
phone.sendEmail();
}, "AA").start();
TimeUnit.SECONDS.sleep(2);
new Thread(() -> {
phone.sendSMS();
// phone2.sendSMS();
}, "BB").start();
}
}
//手机资源类,带发邮件、发短信功能
class Phone {
//发邮件
static synchronized void sendEmail() {
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("sendEmail----->");
}
//发短信
synchronized void sendSMS() {
System.out.println("sendSMS------->");
}
void sayHello() {
System.out.println("sayHello------>");
}
}
结果
场景八
1
个静态同步方法 一个普通同步方法 两部部手机
package com.zbiti.juc;
import java.util.concurrent.TimeUnit;
public class LockDemo {
public static void main(String[] args) throws InterruptedException {
Phone phone = new Phone();
Phone phone2 = new Phone();
new Thread(() -> {
phone.sendEmail();
}, "AA").start();
TimeUnit.SECONDS.sleep(2);
new Thread(() -> {
// phone.sendSMS();
phone2.sendSMS();
}, "BB").start();
}
}
//手机资源类,带发邮件、发短信功能
class Phone {
//发邮件
static synchronized void sendEmail() {
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("sendEmail----->");
}
//发短信
synchronized void sendSMS() {
System.out.println("sendSMS------->");
}
void sayHello() {
System.out.println("sayHello------>");
}
}
结果
锁当前实例对象和锁当前类的Class
对象是两个不同的对象,所以静态同步方法和非静态同步方法之间是不会有竞态条件的。但是一旦一个静态同步方法获取锁后,其它的静态同步方法都必须等待该方法释放锁后才能获取锁,而不管是同一个实例对象的静态同步方法之间,还是不同的实例对象静态同步方法之间
本文由博客一文多发平台 OpenWrite 发布!
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦