首页 / JAVA / Java多线程之八锁问题
Java多线程之八锁问题
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Java多线程之八锁问题,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含5853字,纯文字阅读大概需要9分钟。
内容图文
![Java多线程之八锁问题](/upload/InfoBanner/zyjiaocheng/617/d7bf1aaf6a454122b9bf4f3823d1c5c9.jpg)
1 八锁现象
- 问题一:标准访问,先打印短信还是邮件?
public class Lock_8_1 {
public static void main(String[] args) throws Exception {
Phone phone = new Phone();
new Thread(() -> { phone.sendSMS(); }, "AA").start();
TimeUnit.SECONDS.sleep(1);
new Thread(() -> { phone.sendEmail(); }, "BB").start();
}
}
class Phone {
public synchronized void sendSMS() {
System.out.println("------sendSMS");
}
public synchronized void sendEmail() {
System.out.println("------sendEmail");
}
public void getHello() {
System.out.println("------getHello");
}
}/*sendSMS*/
- 问题二:停4秒在短信方法内,先打印短信还是邮件?
public class Lock_8_2 {
public static void main(String[] args) throws Exception {
Phone phone = new Phone();
new Thread(() -> { phone.sendSMS(); }, "AA").start();
TimeUnit.SECONDS.sleep(1);
new Thread(() -> { phone.sendEmail(); }, "BB").start();
}
}
class Phone {
public synchronized void sendSMS() {
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("------sendSMS");
}
public synchronized void sendEmail() {
System.out.println("------sendEmail");
}
}/*sendSMS*/
- 问题三:新增普通的getHello方法,是先打印短信还是hello?
public class Lock_8_3 {
public static void main(String[] args) throws Exception {
Phone phone = new Phone();
new Thread(() -> { phone.sendSMS(); }, "AA").start();
TimeUnit.SECONDS.sleep(1);
new Thread(() -> { phone.getHello(); }, "BB").start();
}
}
class Phone {
public synchronized void sendSMS() {
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("------sendSMS");
}
public synchronized void sendEmail() {
System.out.println("------sendEmail");
}
public void getHello() {
System.out.println("------getHello");
}
}/*getHello*/
- 问题四:现在有两部手机,先打印短信还是邮件?
public class Lock_8_4 {
public static void main(String[] args) throws Exception {
Phone phone1 = new Phone();
Phone phone2 = new Phone();
new Thread(() -> { phone1.sendSMS(); }, "AA").start();
TimeUnit.SECONDS.sleep(1);
new Thread(() -> { phone2.sendEmail(); }, "BB").start();
}
}
class Phone {
public synchronized void sendSMS() {
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("------sendSMS");
}
public synchronized void sendEmail() {
System.out.println("------sendEmail");
}
}/*sendEmail*/
- 问题五:两个静态同步方法,1部手机,先打印短信还是邮件?
public class Lock_8_5 {
public static void main(String[] args) throws Exception {
Phone phone = new Phone();
new Thread(() -> { phone.sendSMS(); }, "AA").start();
TimeUnit.SECONDS.sleep(1);
new Thread(() -> { phone.sendEmail(); }, "BB").start();
}
}
class Phone {
public static synchronized void sendSMS() {
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("------sendSMS");
}
public static synchronized void sendEmail() {
System.out.println("------sendEmail");
}
}/*sendSMS*/
- 问题六:两个静态同步方法,2部手机,先打印短信还是邮件?
public class Lock_8_6 {
public static void main(String[] args) throws Exception {
Phone phone = new Phone();
Phone phone2 = new Phone();
new Thread(() -> { phone.sendSMS(); }, "AA").start();
TimeUnit.SECONDS.sleep(1);
new Thread(() -> { phone2.sendEmail(); }, "BB").start();
}
}
class Phone {
public static synchronized void sendSMS() {
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("------sendSMS");
}
public static synchronized void sendEmail() {
System.out.println("------sendEmail");
}
}/*sendSMS*/
- 问题七:1个静态同步方法,1个普通同步方法,1部手机,先打印短信还是邮件?
public class Lock_8_7 {
public static void main(String[] args) throws Exception {
Phone phone = new Phone();
new Thread(() -> { phone.sendSMS(); }, "AA").start();
TimeUnit.SECONDS.sleep(1);
new Thread(() -> { phone.getHello(); }, "BB").start();
}
}
class Phone {
public static synchronized void sendSMS() {
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("------sendSMS");
}
public synchronized void sendEmail() {
System.out.println("------sendEmail");
}
}/*sendEmail*/
- 问题八:1个静态同步方法,1个普通同步方法,2部手机,先打印短信还是邮件
public class Lock_8_8 {
public static void main(String[] args) throws Exception {
Phone phone = new Phone();
Phone phone2 = new Phone();
new Thread(() -> { phone.sendSMS(); }, "AA").start();
TimeUnit.SECONDS.sleep(1);
new Thread(() -> { phone2.sendEmail(); }, "BB").start();
}
}
class Phone {
public static synchronized void sendSMS() {
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("------sendSMS");
}
public synchronized void sendEmail() {
System.out.println("------sendEmail");
}
}/*sendEmail*/
2 多线程锁
- synchronized实现同步的基础:Java中的每一个对象都可以作为锁。具体表现为以下3种形式。
- 对于普通同步方法,锁是当前实例对象。
- 对于静态同步方法,锁是当前类的Class对象。
- 对于同步方法块,锁是Synchonized括号里配置的对象
- 当一个线程试图访问同步代码块时,它首先必须得到锁,退出或抛出异常时必须释放锁。
- 如果一个实例对象的非静态同步方法获取锁后,该实例对象的其他非静态同步方法必须等待获取锁的方法释放锁后才能获取锁
- 一个对象里面如果有多个synchronized方法,某一个时刻内,只要一个线程去调用其中的一个synchronized方法了,其它的线程都只能等待,换句话说,某一个时刻内,只能有唯一一个线程去访问这些synchronized方法,锁的是当前对象this,被锁定后,其它的线程都不能进入到当前对象的其它的synchronized方法(问题一、问题二)
- 不同的实例对象的非静态同步方法因为锁的是各自的实例对象,所以互不影响(问题四)
- 加个普通方法后发现和同步锁无关(问题三)
- 所有的静态同步方法用的也是同一把锁——类对象本身,一旦一个静态同步方法获取锁后,其他的静态同步方法都必须等待该方法释放锁后才能获取锁,而不管是同一个实例对象的静态同步方法之间,还是不同的实例对象的静态同步方法之间,它们只有同一个类的实例对象class!(问题五、问题六)
- 实例对象锁与类的class对象锁,是两个不同的对象,所以静态同步方法与非静态同步方法之间是不会有竞态条件的。(问题七、问题八)
内容总结
以上是互联网集市为您收集整理的Java多线程之八锁问题全部内容,希望文章能够帮你解决Java多线程之八锁问题所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。