1.标准访问,请问先打印邮件还是短信?
答案:
锁住当前的 phone对象 (this) 两个线程竞争的同一把锁
A*********sendEmail
B*********sendSMS
class Phone{
public synchronized void sendEmail() throws Exception{
System.out.println(Thread.currentThread().getName()+"*********sendEmail");
}
public synchronized void sendSMS()throws Exception{
System.out.println(Thread.currentThread().getName()+"*********sendSMS");
}
}
public class Lock8Demo5 {
public static void main(String[] args) throws Exception {
Phone phone = new Phone();
new Thread(()->{
try {
phone.sendEmail();
} catch (Exception e) {
e.printStackTrace();
}
},"A").start();
TimeUnit.SECONDS.sleep(1);
new Thread(()->{
try {
phone.sendSMS();
} catch (Exception e) {
e.printStackTrace();
}
},"B").start();
}
}
2.暂停四秒中在邮件方法 请问先打印邮件还是短信?
答案:
锁住当前的Phone对象 (this)
A*********sendEmail
//...睡眠四秒中后
B*********sendSMS
class Phone{
public synchronized void sendEmail() throws Exception{
//暂停四秒钟
TimeUnit.SECONDS.sleep(4);
System.out.println(Thread.currentThread().getName()+"*********sendEmail");
}
public synchronized void sendSMS()throws Exception{
System.out.println(Thread.currentThread().getName()+"*********sendSMS");
}
}
public class Lock8Demo5 {
public static void main(String[] args) throws Exception {
Phone phone = new Phone();
new Thread(()->{
try {
phone.sendEmail();
} catch (Exception e) {
e.printStackTrace();
}
},"A").start();
TimeUnit.SECONDS.sleep(1);
new Thread(()->{
try {
phone.sayHello();
} catch (Exception e) {
e.printStackTrace();
}
},"B").start();
}
}
3.新增普通SayHello方法 ,请问先打印邮件还是hello
答案:
B*********sayHello
A*********sendEmail
class Phone{
public synchronized void sendEmail() throws Exception{
//暂停四秒钟
TimeUnit.SECONDS.sleep(4);
System.out.println(Thread.currentThread().getName()+"*********sendEmail");
}
public synchronized void sendSMS()throws Exception{
System.out.println(Thread.currentThread().getName()+"*********sendSMS");
}
public void sayHello()throws Exception{
System.out.println(Thread.currentThread().getName()+"*********sayHello");
}
}
public class Lock8Demo5 {
public static void main(String[] args) throws Exception {
Phone phone = new Phone();
new Thread(()->{
try {
phone.sendEmail();
} catch (Exception e) {
e.printStackTrace();
}
},"A").start();
TimeUnit.SECONDS.sleep(1);
new Thread(()->{
try {
phone.sayHello();
} catch (Exception e) {
e.printStackTrace();
}
},"B").start();
}
}
4.两部手机,请问先打印邮件还是短信
答案:
B*********sendSMS
A*********sendEmail
class Phone{
public synchronized void sendEmail() throws Exception{
//暂停四秒钟
TimeUnit.SECONDS.sleep(4);
System.out.println(Thread.currentThread().getName()+"*********sendEmail");
}
public synchronized void sendSMS()throws Exception{
System.out.println(Thread.currentThread().getName()+"*********sendSMS");
}
public void sayHello()throws Exception{
System.out.println(Thread.currentThread().getName()+"*********sayHello");
}
}
public class Lock8Demo5 {
public static void main(String[] args) throws Exception {
Phone phone1 = new Phone();
Phone phone2 = new Phone();
new Thread(()->{
try {
phone1.sendEmail();
} catch (Exception e) {
e.printStackTrace();
}
},"A").start();
TimeUnit.SECONDS.sleep(1);
new Thread(()->{
try {
phone2.sendSMS();
} catch (Exception e) {
e.printStackTrace();
}
},"B").start();
}
}
5.两个静态同步方法,同一部手机,请问先打印邮件 还是短信?
答案:
静态锁的是Class -会阻塞
A*********sendEmail
B*********sendSMS
class Phone{
public static synchronized void sendEmail() throws Exception{
//暂停四秒钟
TimeUnit.SECONDS.sleep(4);
System.out.println(Thread.currentThread().getName()+"*********sendEmail");
}
public static synchronized void sendSMS()throws Exception{
System.out.println(Thread.currentThread().getName()+"*********sendSMS");
}
public void sayHello()throws Exception{
System.out.println(Thread.currentThread().getName()+"*********sayHello");
}
}
public class Lock8Demo5 {
public static void main(String[] args) throws Exception {
Phone phone1 = new Phone();
Phone phone2 = new Phone();
new Thread(()->{
try {
phone1.sendEmail();
} catch (Exception e) {
e.printStackTrace();
}
},"A").start();
TimeUnit.SECONDS.sleep(1);
new Thread(()->{
try {
phone1.sendSMS();
} catch (Exception e) {
e.printStackTrace();
}
},"B").start();
}
}
6.两个静态同步方法,两部手机,请问先打印邮件 还是短信?
答案:
静态锁的是Class -会阻塞
A*********sendEmail
B*********sendSMS
class Phone{
public static synchronized void sendEmail() throws Exception{
//暂停四秒钟
TimeUnit.SECONDS.sleep(4);
System.out.println(Thread.currentThread().getName()+"*********sendEmail");
}
public static synchronized void sendSMS()throws Exception{
System.out.println(Thread.currentThread().getName()+"*********sendSMS");
}
public void sayHello()throws Exception{
System.out.println(Thread.currentThread().getName()+"*********sayHello");
}
}
public class Lock8Demo5 {
public static void main(String[] args) throws Exception {
Phone phone1 = new Phone();
Phone phone2 = new Phone();
new Thread(()->{
try {
phone1.sendEmail();
} catch (Exception e) {
e.printStackTrace();
}
},"A").start();
TimeUnit.SECONDS.sleep(1);
new Thread(()->{
try {
phone2 .sendSMS();
} catch (Exception e) {
e.printStackTrace();
}
},"B").start();
}
}
7.一个静态同步方法,一个普通同步方法 同一部手机,请问先打印邮件 还是短信?
答案:
B*********sendSMS
A*********sendEmail
class Phone{
public static synchronized void sendEmail() throws Exception{
//暂停四秒钟
TimeUnit.SECONDS.sleep(4);
System.out.println(Thread.currentThread().getName()+"*********sendEmail");
}
public synchronized void sendSMS()throws Exception{
System.out.println(Thread.currentThread().getName()+"*********sendSMS");
}
}
public class Lock8Demo5 {
public static void main(String[] args) throws Exception {
Phone phone1 = new Phone();
Phone phone2 = new Phone();
new Thread(()->{
try {
phone1.sendEmail();
} catch (Exception e) {
e.printStackTrace();
}
},"A").start();
TimeUnit.SECONDS.sleep(1);
new Thread(()->{
try {
phone1.sendSMS();
} catch (Exception e) {
e.printStackTrace();
}
},"B").start();
}
}
8.一个静态同步方法,一个普通同步方法 两部手机,请问先打印邮件 还是短信?
答案:
B*********sendSMS
A*********sendEmail
class Phone{
public static synchronized void sendEmail() throws Exception{
//暂停四秒钟
TimeUnit.SECONDS.sleep(4);
System.out.println(Thread.currentThread().getName()+"*********sendEmail");
}
public synchronized void sendSMS()throws Exception{
System.out.println(Thread.currentThread().getName()+"*********sendSMS");
}
}
public class Lock8Demo5 {
public static void main(String[] args) throws Exception {
Phone phone1 = new Phone();
Phone phone2 = new Phone();
new Thread(()->{
try {
phone1.sendEmail();
} catch (Exception e) {
e.printStackTrace();
}
},"A").start();
TimeUnit.SECONDS.sleep(1);
new Thread(()->{
try {
phone2.sendSMS();
} catch (Exception e) {
e.printStackTrace();
}
},"B").start();
}
}
结论:static 锁的是Class类(类锁) 非static 锁的是 对象(对象锁),判断两个线程竞争的是不是同一把锁
总结:
对象锁:
一个对象里面如果有多个synchronized 方法,某一个时间内,只要有一个线程调用其中一个synchronized 方法了,其他线程只能等待,换句话说,某一个时间内,只能唯有一个线程访问这些synchronized 方法
总结:锁的是当前对象this,被锁定后,其他的线程都不能进入到当前对象的其他synchronized 方法
非synchronized 不与 非静态 synchronized 竞争同一把锁