多线程锁的练习题

1、标准访问,先打印短信还是邮件

class  Phone {
public synchronized void sendSMS() throws Exception
{
Thread.sleep(400);题【2】添加延时
System. out .println( "------sendSMS" );
} public synchronized void sendEmail() throws Exception
{
System. out .println( "------sendEmail" );
}
public void getHello()
{
System. out .println( "------getHello" );
} }
public class MoreThreadLock {
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(); }
}

------sendSMS
------sendEmail

2、停4秒在短信方法内,先打印短信还是邮件

  ------sendSMS
  ------sendEmail

3、普通的hello方法,是先打短信还是hello ,

hello方法是普通方法,短信进程需要四秒

public class MoreThreadLock {
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);//主线程睡1秒,为了区分谁先执行 new Thread(() -> { try { phone.getHello(); //phone2.sendEmail(); } catch (Exception e ) { e .printStackTrace(); } }, "BB" ).start(); }
}

4、现在有两部手机,先打印短信还是邮件

public class MoreThreadLock {
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 { phone2.sendEmail(); } catch (Exception e ) { e .printStackTrace(); } }, "BB" ).start(); }
}

------sendEmail
------sendSMS

5、 两个静态同步方法,1部手机,先打印短信还是邮件

class  Phone {
public static synchronized void sendSMS() throws Exception
{
Thread.sleep(400);题【2】添加延时
System. out .println( "------sendSMS" );
} public static synchronized void sendEmail() throws Exception
{
System. out .println( "------sendEmail" );
} }

------sendSMS
------sendEmail

6、两个静态同步方法,2部手机,先打印短信还是邮件

public class MoreThreadLock {
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);//主线程睡1秒,为了区分谁先执行 new Thread(() -> { try { phone2.sendEmail(); } catch (Exception e ) { e .printStackTrace(); } }, "BB" ).start(); }
}
4、现在有两部手机,先打印短信还是邮件 public class MoreThreadLock {
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 { phone2.sendEmail(); } catch (Exception e ) { e .printStackTrace(); } }, "BB" ).start(); }
}

------sendSMS
------sendEmail

7、1个静态同步方法,1个普通同步方法,1部手机,先打印短信还是邮件

class  Phone {
public static synchronized void sendSMS() throws Exception
{
Thread.sleep(400);题【2】添加延时
System. out .println( "------sendSMS" );
} public synchronized void sendEmail() throws Exception
{
System. out .println( "------sendEmail" );
} }

------sendEmail
------sendSMS

8、1个静态同步方法,1个普通同步方法,2部手机,先打印短信还是邮件

class  Phone {
public static synchronized void sendSMS() throws Exception
{
Thread.sleep(400);题【2】添加延时
System. out .println( "------sendSMS" );
} public synchronized void sendEmail() throws Exception
{
System. out .println( "------sendEmail" );
} }

------sendEmail
------sendSMS

总结:

A 一个对象里面如果有多个synchronized方法,某一个时刻内,只要一个线程去调用其中的一个synchronized方法了,

其它的线程都只能等待,换句话说,某一个时刻内,只能有唯一一个线程去访问这些synchronized方法

锁的是当前对象this,被锁定后,其它的线程都不能进入到当前对象的其它的synchronized方法

加个普通方法后发现和同步锁无关

换成两个对象后,不是同一把锁了,情况立刻变化。

synchronized实现同步的基础:Java中的每一个对象都可以作为锁。

具体表现为以下3种形式。

对于普通同步方法,锁是当前实例对象。

对于静态同步方法,锁是当前类的Class对象。

对于同步方法块,锁是 Synchonized 括号里配置的对象

当一个线程试图访问同步代码块时,它首先必须得到锁,退出或抛出异常时必须释放锁。

也就是说如果一个实例对象的非静态同步方法获取锁后,该实例对象的其他非静态同步方法必须等待获取锁的方法释放锁后才能获取锁,

可是别的实例对象的非静态同步方法因为跟该实例对象的非静态同步方法用的是不同的锁,

所以毋须等待该实例对象已获取锁的非静态同步方法释放锁就可以获取他们自己的锁。

所有的静态同步方法用的也是同一把锁——类对象本身,

这两把锁是两个不同的对象,所以静态同步方法与非静态同步方法之间是不会有竞态条件的。

但是一旦一个静态同步方法获取锁后,其他的静态同步方法都必须等待该方法释放锁后才能获取锁,

而不管是同一个实例对象的静态同步方法之间,

还是不同的实例对象的静态同步方法之间,只要它们同一个类的实例对象!

最新文章

  1. 总结js常用函数和常用技巧(持续更新)
  2. Hdu 2845 Beans
  3. 【C语言学习】《C Primer Plus》第3章 数据和C
  4. hdu 1255
  5. 【erlang】erlang几种生成随机数的方法
  6. poj 1330 LCA
  7. 20145211 《Java程序设计》第10周学习总结——昨夜星辰昨夜风
  8. 对同一个项目下的多个数据库Context进行迁移Migrations
  9. HDU 1698 Just a Hook 区间更新 lazy标记
  10. intent.addFlags
  11. GDAL库——读取图像并提取基本信息
  12. Jenkins(二) 安装、新建Jobs与删除及SVN配置(转)
  13. PAT乙级1001. 害死人不偿命的(3n+1)猜想 (15)
  14. jmeter线程组配置
  15. vue.cli脚手架初次使用图文教程
  16. IDEA鼠标显示javadoc的设置
  17. The 'INFORMATION_SCHEMA.GLOBAL_STATUS' feature is disabled; see the documentation for 'show_compatibility_56'
  18. SQLServer删除登录记录用户名和密码
  19. linux执行系统命令时挂起
  20. 增量式pid和位置式PID参数整定过程对比

热门文章

  1. git rebase -- 能够将分叉的分支重新合并.
  2. MySQL 8 InnoDB 集群管理
  3. npm常用模块之bable使用
  4. Spring boot mvn
  5. 用友UAP NC 开发环境抛出"JDK默认编辑器找不到"
  6. 手动部署:在eclipse导入web项目并更新包到本地部署
  7. hackintosh和windows时区问题
  8. 【剑指Offer】04、重建二叉树
  9. VS中关于数据库的操作
  10. vue-routerV3.1版本报错:message: "Navigating to current location ("/home") is not allowed",