嘉兴旅游:多线程之8锁问题

admin 5个月前 (05-03) 科技 39 0

Phone 有两个方式:发送邮件和发送短信,每个方式都打印一句话,现在通过差别的方式对方式举行操作,回答出打印的先后顺序(建议先自己看代码认真思考,然后再看谜底,文章末端会对每个问题举行剖析)

问题

1、尺度接见,两线程中心睡眠 2 毫秒,先打印邮件照样短信?

class Phone {
    public synchronized void sendEmail() {
        System.out.println("send email");
    }
    public synchronized void sendSms() {
        System.out.println("send sms");
    }
}

public class Lock01 {
    public static void main(String[] args) throws InterruptedException {
        Phone phone = new Phone();
        new Thread(() -> phone.sendEmail(), "A").start();
        Thread.sleep(200);
        new Thread(() -> phone.sendSms(), "B").start();
    }
}
查看谜底 send email
send sms

2、在 sendEmail() 方式中睡眠 4 秒,先打印邮件照样短信?

class Phone {
    public synchronized void sendEmail() {
        try {
            Thread.sleep(4000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("send email");
    }
    public synchronized void sendSms() {
        System.out.println("send sms");
    }
}

public class Lock02 {
    public static void main(String[] args) throws InterruptedException {
        Phone phone = new Phone();
        new Thread(() -> phone.sendEmail(), "A").start();
        Thread.sleep(200);
        new Thread(() -> phone.sendSms(), "B").start();
    }
}
查看谜底 send email
send sms

3、添加通俗的 hello() 方式,先打印邮件照样 hello?

class Phone {
    public synchronized void sendEmail() {
        try {
            Thread.sleep(4000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("send email");
    }
    public void hello() {
        System.out.println("hello");
    }
}
public class Lock03 {
    public static void main(String[] args) throws InterruptedException {
        Phone phone = new Phone();
        new Thread(() -> phone.sendEmail(), "A").start();
        Thread.sleep(200);
        new Thread(() -> phone.hello(), "B").start();
    }
}
查看谜底 hello
send email

4、2 个手机,先打印邮件照样短信?

class Phone {
    public synchronized void sendEmail() {
        try {
            Thread.sleep(4000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("send email");
    }

    public synchronized void sendSms() {
        System.out.println("send sms");
    }
}

public class Lock04 {
    public static void main(String[] args) throws InterruptedException {
        Phone phone1 = new Phone();
        Phone phone2 = new Phone();
        new Thread(() -> phone1.sendEmail(), "A").start();
        Thread.sleep(200);
        new Thread(() -> phone2.sendSms(), "B").start();
    }
}
查看谜底 send sms
send email

5、2个静态同步方式,1部手机,先打印邮件照样短信?

class Phone {
    public static synchronized void sendEmail() {
        try {
            Thread.sleep(4000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("send email");
    }

    public static synchronized void sendSms() {
        System.out.println("send sms");
    }
}

public class Lock05 {
    public static void main(String[] args) throws InterruptedException {
        Phone phone = new Phone();
        new Thread(() -> phone.sendEmail(), "A").start();
        Thread.sleep(200);
        new Thread(() -> phone.sendSms(), "B").start();
    }
}
查看谜底 send email
send sms **6、2个静态同步方式,2部手机,先打印邮件照样短信?**
class Phone {
    public static synchronized void sendEmail() {
        try {
            Thread.sleep(4000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("send email");
    }

    public static synchronized void sendSms() {
        System.out.println("send sms");
    }
}

public class Lock06 {
    public static void main(String[] args) throws InterruptedException {
        Phone phone1 = new Phone();
        Phone phone2 = new Phone();
        new Thread(() -> phone1.sendEmail(), "A").start();
        Thread.sleep(200);
        new Thread(() -> phone2.sendSms(), "B").start();
    }
}
查看谜底 send email
send sms **7、1个静态同步方式,1个通俗同步方式,1部手机,先打印邮件照样短信?**
class Phone {
    public static synchronized void sendEmail() {
        try {
            Thread.sleep(4000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("send email");
    }

    public synchronized void sendSms() {
        System.out.println("send sms");
    }
}

public class Lock07 {
    public static void main(String[] args) throws InterruptedException {
        Phone phone = new Phone();
        new Thread(() -> phone.sendEmail(), "A").start();
        Thread.sleep(200);
        new Thread(() -> phone.sendSms(), "B").start();
    }
}
查看谜底 send sms
send email

8、1个静态同步方式,1个通俗同步方式,2部手机,先打印邮件照样短信?

class Phone {
    public static synchronized void sendEmail() {
        try {
            Thread.sleep(4000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("send email");
    }

    public synchronized void sendSms() {
        System.out.println("send sms");
    }
}

public class Lock08 {
    public static void main(String[] args) throws InterruptedException {
        Phone phone1 = new Phone();
        Phone phone2 = new Phone();
        new Thread(() -> phone1.sendEmail(), "A").start();
        Thread.sleep(200);
        new Thread(() -> phone2.sendSms(), "B").start();
    }
}
查看谜底 send sms
send email

剖析

问题一

当一个工具里有多个同步(synchronized)方式,有一个线程接见了其中一个同步方式,其它线程只能守候其接见完成后才气接见,由于此时锁的是当前工具 this,其它的线程都不能进入到当前工具的其它的同步方式。

若是没有添加 Thread.sleep(200); 则打印的顺序是不一定的,由于线程的调剂和操作系统有关。 添加 Thread.sleep(200); 则保证了线程 A 比 B 先执行。

问题二

由于线程 A 先执行,会先挪用 sendEmail() 方式,Phone 实例就会被锁住,线程 B 只能守候 A 执行完在执行。

问题三

hello() 方式并不是同步方式,因此不受锁的影响。

问题四

现在有两个实例,前面我们说过,synchronized 锁的是 this,以是会发生两把锁,它们之间互不滋扰,谁先执行完谁就先打印。

问题五、问题六

synchronized 实现同步的基础:Java 中的每一个工具都可以作为锁,具体表现为以下三种形式:

  • 对于通俗同步方式,锁的是当前实例工具 this
  • 对于静态同步方式,锁的是当前类的 Class 工具
  • 对于同步方式块,锁是Synchonized括号里设置的工具

以是,无论是 1 个工具照样 2 个工具,静态同步方式锁的都是 Class,只能根据线程执行的顺序打印。

问题七、问题八

这两种情形都是 1 个静态同步方式,1 个非静态同步方式,它们的锁都不是同一个工具,因此相互不受影响

总结

1、当一个线程试图接见同步代码块时,它首先必须获得锁,退出或抛出异常时必须释放锁。

2、Java 中的每一个工具都可以作为锁;通俗同步方式锁 this,静态同步方式锁 Class,同步方式块锁括号;

3、只要锁的工具不是同一个,就直接根据线程执行的快慢来决议;锁的工具是同一个,就根据线程进入的先后顺序决议。

只要掌握了锁的工具是什么,无论是 8 锁照样 100 锁都不在话下!

,

sunbet

Sunbet www.ipvps.cn致力于打造申博娱乐平台,门下的申博打造拥有最让消费者更安心体验环境!Sunbet一个让您宾至如归的老牌网站!

Allbet声明:该文看法仅代表作者自己,与本平台无关。转载请注明:嘉兴旅游:多线程之8锁问题

网友评论

  • (*)

最新评论

站点信息

  • 文章总数:1447
  • 页面总数:0
  • 分类总数:8
  • 标签总数:2650
  • 评论总数:313
  • 浏览总数:31953