关于synochronized的八个问题
1 标准访问,先打印短信还是邮件 短信
class Phone
{
public synchronized void sendSMS() throws Exception
{
System.out.println("------sendSMS");
}
public synchronized void sendEmail() throws Exception
{
System.out.println("------sendEmail");
}
public void getHello()
{
System.out.println("------getHello");
}
}
public class Lock_8
{
public static void main(String[] args) throws Exception
{
Phone phone = new Phone();
Phone phone2 = new Phone();
new Thread(() -> {
try {
phone.sendSMS();
} catch (Exception e) {
e.printStackTrace();
}
}, "AA").start();
Thread.sleep(100);
new Thread(() -> {
try {
phone.sendEmail();
// phone.getHello();
// phone2.sendEmail();
} catch (Exception e) {
e.printStackTrace();
}
}, "BB").start();
}
}
答案是短信,解释如下:标准访问:各线程和个方法中都没有睡眠时间,此时可能先打印短信,也可能先打印邮件,但是在打印短信的线程后面加上睡眠100毫秒,那就是先打印短信,因为一个对象里面如果有多个synchronized方法,某一个时刻内,只要一个线程去调用其中的一个synchronized方法了,其它的线程都只能等待,换句话说,某一个时刻内,只能有唯一一个线程去访问这些synchronized方法
2 停4秒在短信方法内,先打印短信还是邮件 短信
class Phone
{
public synchronized void sendSMS() throws Exception
{
TimeUnit.SECONDS.sleep(4);
System.out.println("------sendSMS");
}
public synchronized void sendEmail() throws Exception
{
System.out.println("------sendEmail");
}
public void getHello()
{
System.out.println("------getHello");
}
}
public class Lock_8
{
public static void main(String[] args) throws Exception
{
Phone phone = new Phone();
Phone phone2 = new Phone();
new Thread(() -> {
try {
phone.sendSMS();
} catch (Exception e) {
e.printStackTrace();
}
}, "AA").start();
Thread.sleep(1000);
new Thread(() -> {
try {
phone.sendEmail();
// phone.getHello();
// phone2.sendEmail();
} catch (Exception e) {
e.printStackTrace();
}
}, "BB").start();
}
}
答案是短信,解释如下:只要打印短信后面有100毫秒的睡眠时间,那么先打印的就是短信,因为一个对象里面如果有多个synchronized方法,某一个时刻内,只要一个线程去调用其中的一个synchronized方法了,其它的线程都只能等待
3 新增普通的hello方法,是先打短信还是hello (短信方法中有睡眠4秒) hello
class Phone
{
public synchronized void sendSMS() throws Exception
{
TimeUnit.SECONDS.sleep(4);
System.out.println("------sendSMS");
}
public synchronized void sendEmail() throws Exception
{
System.out.println("------sendEmail");
}
public void getHello()
{
System.out.println("------getHello");
}
}
public class Lock_8
{
public static void main(String[] args) throws Exception
{
Phone phone = new Phone();
Phone phone2 = new Phone();
new Thread(() -> {
try {
phone.sendSMS();
} catch (Exception e) {
e.printStackTrace();
}
}, "AA").start();
Thread.sleep(1000);
new Thread(() -> {
try {
//phone.sendEmail();
phone.getHello();
// phone2.sendEmail();
} catch (Exception e) {
e.printStackTrace();
}
}, "BB").start();
}
}
答案是hello,只要打印短信的方法中有睡眠4秒的代码,那么就是先打印hello,因为普通方法不在synchronized锁的范围内,所以打印hello的线程不受影响
4 现在有两部手机,先打印短信还是邮件(短信方法中有睡眠4秒) 邮件
class Phone
{
public synchronized void sendSMS() throws Exception
{
TimeUnit.SECONDS.sleep(4);
System.out.println("------sendSMS");
}
public synchronized void sendEmail() throws Exception
{
System.out.println("------sendEmail");
}
public void getHello()
{
System.out.println("------getHello");
}
}
public class Lock_8
{
public static void main(String[] args) throws Exception
{
Phone phone = new Phone();
Phone phone2 = new Phone();
new Thread(() -> {
try {
phone.sendSMS();
} catch (Exception e) {
e.printStackTrace();
}
}, "AA").start();
Thread.sleep(1000);
new Thread(() -> {
try {
//phone.sendEmail();
//phone.getHello();
phone2.sendEmail();
} catch (Exception e) {
e.printStackTrace();
}
}, "BB").start();
}
}
先打印邮件,因为这是两个对象,其各自的线程不再是同一把锁,因为打印短信方法有4秒的延迟,所以先打印邮件
5 两个静态同步方法,1部手机,先打印短信还是邮件(短信方法中有睡眠4秒) 短信
class Phone
{
public synchronized static void sendSMS() throws Exception
{
TimeUnit.SECONDS.sleep(4);
System.out.println("------sendSMS");
}
public synchronized static void sendEmail() throws Exception
{
System.out.println("------sendEmail");
}
public void getHello()
{
System.out.println("------getHello");
}
}
public class Lock_8
{
public static void main(String[] args) throws Exception
{
Phone phone = new Phone();
Phone phone2 = new Phone();
new Thread(() -> {
try {
phone.sendSMS();
} catch (Exception e) {
e.printStackTrace();
}
}, "AA").start();
Thread.sleep(1000);
new Thread(() -> {
try {
//phone.sendEmail();
//phone.getHello();
phone2.sendEmail();
} catch (Exception e) {
e.printStackTrace();
}
}, "BB").start();
}
}
答案是短信 解释:synchronized实现同步的基础:Java中的每一个对象都可以作为锁。
具体表现为以下3种形式。
对于普通同步方法,锁是当前实例对象。
对于静态同步方法,锁是当前类的Class对象。
对于同步方法块,锁是Synchonized括号里配置的对象
问题5中synchronized修饰的是静态同步方法,所以锁的是当前类的Class对象,先获取锁的线程先执行,由于打印邮件线程前有100毫秒的延迟,所以打印短信的线程先获取锁,所以先打印短信
6 两个静态同步方法,2部手机,先打印短信还是邮件(短信方法中有睡眠4秒) 短信
class Phone
{
public synchronized static void sendSMS() throws Exception
{
TimeUnit.SECONDS.sleep(4);
System.out.println("------sendSMS");
}
public synchronized static void sendEmail() throws Exception
{
System.out.println("------sendEmail");
}
public void getHello()
{
System.out.println("------getHello");
}
}
public class Lock_8
{
public static void main(String[] args) throws Exception
{
Phone phone = new Phone();
Phone phone2 = new Phone();
new Thread(() -> {
try {
phone.sendSMS();
} catch (Exception e) {
e.printStackTrace();
}
}, "AA").start();
Thread.sleep(1000);
new Thread(() -> {
try {
//phone.sendEmail();
//phone.getHello();
phone2.sendEmail();
} catch (Exception e) {
e.printStackTrace();
}
}, "BB").start();
}
}
同上答案相同,也是打印短信,因为synchronized修饰的是两个静态同步方法,锁的是当前类的Class对象,是同一把锁,所以先打印短信
7 1个静态同步方法,1个普通同步方法,1部手机,先打印短信还是邮件(短信方法中有睡眠4秒) 邮件
class Phone
{
public synchronized static void sendSMS() throws Exception
{
TimeUnit.SECONDS.sleep(4);
System.out.println("------sendSMS");
}
public synchronized void sendEmail() throws Exception
{
System.out.println("------sendEmail");
}
public void getHello()
{
System.out.println("------getHello");
}
}
public class Lock_8
{
public static void main(String[] args) throws Exception
{
Phone phone = new Phone();
Phone phone2 = new Phone();
new Thread(() -> {
try {
phone.sendSMS();
} catch (Exception e) {
e.printStackTrace();
}
}, "AA").start();
Thread.sleep(1000);
new Thread(() -> {
try {
//phone.sendEmail();
//phone.getHello();
phone2.sendEmail();
} catch (Exception e) {
e.printStackTrace();
}
}, "BB").start();
}
}
答案是邮件 解释:一个静态同步方法和一个普通方法的synchronized不是同一个锁,虽然修饰静态同步方法的synchronized的锁锁的是当前类的Class对象,但是二者不是同一把锁,所以先打印的是没有延迟的邮件方法
8 1个静态同步方法,1个普通同步方法,2部手机,先打印短信还是邮件(短信方法中有睡眠4秒) 邮件
class Phone
{
public synchronized static void sendSMS() throws Exception
{
TimeUnit.SECONDS.sleep(4);
System.out.println("------sendSMS");
}
public synchronized void sendEmail() throws Exception
{
System.out.println("------sendEmail");
}
public void getHello()
{
System.out.println("------getHello");
}
}
public class Lock_8
{
public static void main(String[] args) throws Exception
{
Phone phone = new Phone();
Phone phone2 = new Phone();
new Thread(() -> {
try {
phone.sendSMS();
} catch (Exception e) {
e.printStackTrace();
}
}, "AA").start();
Thread.sleep(1000);
new Thread(() -> {
try {
//phone.sendEmail();
//phone.getHello();
phone2.sendEmail();
} catch (Exception e) {
e.printStackTrace();
}
}, "BB").start();
}
}
跟上面一样,不是同一把锁,所以先打印的是没有延迟的邮件方法