当前位置: 首页 > wzjs >正文

个人开发游戏郑州做网络优化的公司

个人开发游戏,郑州做网络优化的公司,潍坊网站建设价格,济南建设信用网网站一、锁对象的概念 非静态同步方法:锁的是当前实例对象(this)。当一个实例对象的非静态同步方法获取锁后,该实例对象的其他非静态同步方法必须等待获取锁的方法释放锁后才能获取锁。静态同步方法:锁的是当前类的Class对…

一、锁对象的概念

  • 非静态同步方法锁的是当前实例对象(this)。当一个实例对象的非静态同步方法获取锁后,该实例对象的其他非静态同步方法必须等待获取锁的方法释放锁后才能获取锁。
  • 静态同步方法锁的是当前类的Class对象。当一个静态同步方法获取锁后,其他的静态同步方法都必须等待该方法释放锁后才能获取锁,这种互斥行为适用于同一个类的所有实例对象。
  • 修饰代码块:锁的是括号中的对象。
synchronized(对象){}

二、线程“八锁”

  • 所谓的线程八锁:其实就是从八段代码例子中,理解synchronized的用法,不要太纠结这个名称,不需要纠结八种情况里面好像有些情况是相似的,只需要理解这八个代码例子里面的synchronized 的用法,其他都不用管。(其实就是考察 synchronized 锁住的是哪个对象)
    • 如果纠结这八种情况是否有重复或者是相似的事情,就像我一样掉坑里了,就比如情况一和情况二,它两的区别就是情况二多了一个sleep方法,我当时就一直想,这两种情况不都是一样的嘛,为啥是两种情况呢?唉,他喵的,后来我就悟了,我他喵的想那么多干嘛,我理解它每个情况synchronized 的用法就行了呀。

1情况一:两个线程分别访问 同一个对象(实例对象) 的两个普通同步方法

  • synchronized修饰普通方法默认使用的锁对象是this,由于是同一个对象的两个方法,所以他们的锁对象也是同一个,因此这两个方法会互斥执行。当一个线程执行其中一个方法时,另一个线程必须等待。
    • 因为这里使用的是用一个Number对象n1,所以线程1和线程2锁住的对象都是this(n1),它们是互斥的。
public class Tongbu {public static void main(String[] args) {Number n1 = new Number();
//        当启动多个线程时,线程的执行顺序是不确定的,这主要取决于操作系统的线程调度器。new Thread(()->{ n1.a();}).start();new Thread(()->{ n1.b(); }).start();}}class Number{public synchronized void a() {System.out.println("a()");}public synchronized void b() {System.out.println("b()");}
}
  • 可能出现的结果:
结果1:(先执行第一个线程)
a()
b()结果2:(先执行第二个线程)
b()
a()

情况二:两个线程分别访问 同一个对象(实例对象) 的两个普通同步方法,与情况一相比就多了一个sleep方法

  • synchronized修饰普通方法默认使用的锁对象是this,由于是同一个对象的两个方法,所以他们的锁对象也是同一个,因此这两个方法会互斥执行。当一个线程执行其中一个方法时,另一个线程必须等待。
    • 因为这里使用的是用一个Number对象n1,所以线程1和线程2锁住的对象都是this(n1),它们是互斥的。(sleep方法不会释放锁的
public class Tongbu {public static void main(String[] args) {Number n1 = new Number();
//        当启动多个线程时,线程的执行顺序是不确定的,这主要取决于操作系统的线程调度器。new Thread(()->{ n1.a();}).start();new Thread(()->{ n1.b(); }).start();}}class Number{public synchronized void a() {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("a()");}public synchronized void b() {System.out.println("b()");}
}
  • 可能出现的结果:
结果1:(先执行第一个线程)
-- 等待1s然后输出
a()
b()结果2:(先执行第二个线程)
b()
-- 等待1s然后输出
a()

情况三:在情况二的基础上新增了一个没有被synchronized修饰的普通方法,再启动一个新的线程执行新增的方法

  • synchronized修饰普通方法默认使用的锁对象是this,由于是同一个对象的两个方法,所以他们的锁对象也是同一个,因此这两个方法会互斥执行。当一个线程执行其中一个方法时,另一个线程必须等待。
    • 因为这里使用的是用一个Number对象n1,所以线程1和线程2锁住的对象都是this(n1),它们是互斥的。(sleep方法不会释放锁的),但是c方法没有synchronized 修饰,所以它没有锁,所以c方法启动的时候不会有互斥效果,它的执行不会受到a或b方法执行的影响。
public class Tongbu {public static void main(String[] args) {Number n1 = new Number();
//        当启动多个线程时,线程的执行顺序是不确定的,这主要取决于操作系统的线程调度器。new Thread(()->{ n1.a();}).start();new Thread(()->{ n1.b(); }).start();new Thread(()->{ n1.c(); }).start();}}class Number{public synchronized void a() {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("a()");}public synchronized void b() {System.out.println("b()");}public void c() {System.out.println("c()");}
}
  • 可能出现的结果:
结果1:
c()
-- 等待1s后输出
a()
b()结果2:
c()
b()
-- 等待1s后输出
a()结果3:
b()
c()
-- 等待1s后输出
a()

2情况四:两个线程分别访问两个不同对象的两个普通同步方法:

  • 由于synchronized修饰普通方法默认使用的锁对象是this,由于是两个实例对象,所以它们使用的锁也不同(两个不同的对象,它们的this不一样)。因此,这两个方法可以同时被不同的线程访问,不会互斥
    • 这里的n1和n2不是一个对象实例,所以它俩不互斥。线程1锁住的对象是n1,线程2锁住的对象是n2,这两个线程是并行执行的。
public class Tongbu {public static void main(String[] args) {
//        当启动多个线程时,线程的执行顺序是不确定的,这主要取决于操作系统的线程调度器。Number n1 = new Number();Number n2 = new Number();new Thread(()->{ n1.a();}).start();new Thread(()->{ n2.b(); }).start();}}class Number{public synchronized void a() {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("a()");}public synchronized void b() {System.out.println("b()");}
}
  • 可能出现的结果:
结果1:(即线程2总是先执行完(因为线程1要等待1s))
b()
-- 等待1s后输出
a()

3情况五:一个线程访问访问类的静态同步方法,另一个线程对象的普通同步方法:

  • 由于锁对象不同(一个是类的Class对象,另一个是实例对象this),因此这两个方法不会互斥执行。它们可以同时被不同的线程访问,即它们是同时执行的
public class Tongbu {public static void main(String[] args) {
//        当启动多个线程时,线程的执行顺序是不确定的,这主要取决于操作系统的线程调度器。Number n = new Number();new Thread(()->{ n.a();}).start();new Thread(()->{ n.b(); }).start();}}class Number{public  static  synchronized void a() {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("a()");}public synchronized void b() {System.out.println("b()");}
}
  • 可能出现的结果:
结果1:
b()
-- 等待1s后输出
a()

4情况六:两个线程分别访问同一个类的两个静态同步方法:

  • 由于静态方法默认使用的锁对象是类的Class对象,所以两个线程获取的锁对象都是同一个,因此这两个方法会互斥执行。当一个线程执行其中一个静态方法时,另一个线程必须等待。
public class Tongbu {public static void main(String[] args) {
//        当启动多个线程时,线程的执行顺序是不确定的,这主要取决于操作系统的线程调度器。new Thread(()->{ Number.a();}).start();new Thread(()->{ Number.b(); }).start();}}class Number{public static synchronized void a() {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("a()");}public static synchronized void b() {System.out.println("b()");}
}
  • 可能出现的结果:
结果1:先执行第一个线程
-- 等待1s后输出
a()
b()结果2:先执行第二个线程
b()
-- 等待1s后输出
a()

情况七:两个线程分别访问两个不同对象的静态方法和普通方法:

  • 由于锁对象不同(一个是类的Class对象,另一个是实例对象this),因此这两个方法不会互斥执行。它们可以同时被不同的线程访问,即它们是同时执行的
    • 虽然线程1是使用实例对象调用静态方法a,但是它锁的对象还是Number类.class对象,线程2锁的对象是n2对象(this),所以它们锁的不是同一个对象,所以它们不互斥。
public class Tongbu {public static void main(String[] args) {
//        当启动多个线程时,线程的执行顺序是不确定的,这主要取决于操作系统的线程调度器。Number n1 = new Number();Number n2 = new Number();new Thread(()->{ n1.a();}).start();new Thread(()->{ n2.b(); }).start();}}class Number{public  static  synchronized void a() {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("a()");}public synchronized void b() {System.out.println("b()");}
}
  • 可能出现的结果:
结果1:
b()
-- 等待1s后输出
a()

情况八:两个线程分别访问两个不同对象的两个静态同步方法:

  • 由于静态方法默认使用的锁对象是类的Class对象,所以两个线程获取的锁对象都是同一个,因此这两个方法会互斥执行。当一个线程执行其中一个静态方法时,另一个线程必须等待。
    • 虽然线程1和线程2调用静态a、b方法是两个不同的实例对象,但是它们锁的都是Number.class对象,所以它们锁的是同一个对象,所以它们是互斥的。
public class Tongbu {public static void main(String[] args) {
//        当启动多个线程时,线程的执行顺序是不确定的,这主要取决于操作系统的线程调度器。Number n1 = new Number();Number n2 = new Number();new Thread(()->{ n1.a();}).start();new Thread(()->{ n2.b(); }).start();}}class Number{public static synchronized void a() {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("a()");}public static synchronized void b() {System.out.println("b()");}
}
  • 可能出现的结果:
结果1:(先执行第一个线程)
a()
b()结果2:(先执行第二个线程)
b()
a()

正常来讲,静态方法是有类对象调用的,而不是由类的实例对象调用的(在面向对象编程中,静态方法(static method)是属于类本身的,而不是属于类的某个实例对象。)

  • Java语法允许通过实例对象调用静态方法,这不会引发编译错误或运行时错误。
  • 实例对象调用静态方法时,不会隐式地传递实例对象(即 this 引用),静态方法内无法直接访问实例属性或实例方法(除非通过其他方式获取实例对象的引用)。
http://www.dtcms.com/wzjs/170676.html

相关文章:

  • 阿里云快速做网站目前最新推广平台
  • 专业网站建设在哪里seo 排名 优化
  • 自己怎么建立微网站全网营销的公司
  • 电子商务平台经营者seo公司推荐
  • 做网站可以提些什么意见百度网站快速优化
  • 做搜索网站挣钱seo是什么意思广东话
  • wordpress主题 破解seo入门免费教程
  • 怎样做简单公司网站武汉做seo
  • 成都vi设计十强seo推广策划
  • 网页设计与网站建设课程总结宁波网站推广优化公司怎么样
  • 有经验的聊城网站建设品牌营销经典案例
  • 国外花型设计网站西安seo代理计费
  • 建设银行网站机构特点业务发展佛山网络公司 乐云seo
  • 兄弟们来个能看的企业网站设计优化公司
  • 国内专门做情侣的网站商城网页设计一般用什么软件
  • 自己做交友网站安年软文网
  • 网页建站如何投放网络广告
  • ps图做ppt模板下载网站有哪些网站应该如何推广
  • 最好看免费观看高清大全老师补课日漫陕西seo
  • 网站建设合同服务响应时间公司网站设计方案
  • 外贸购物网站开发哪个搜索引擎最好用
  • 网站备案是需要去哪里做seo排名技术软件
  • 外留网站建设百度2020新版下载
  • 深圳罗湖网站制作公司郑州网站推广方案
  • 青岛网站建设免费视频号视频怎么看下载链接
  • 网站建设素材模板下载推广普通话心得体会
  • 小馋网站建设书樱桃电视剧西瓜视频在线观看
  • 毕业视频代做网站公司seo是什么级别
  • 合肥网站建设pqiw2023今天的新闻联播
  • 知名高端网站设计企业百度热点排行榜