爪哇中的对象级别锁定与类级别锁定
为什么需要同步?
让’借助示例了解这一点。
让’s表示您想计算针对特定URL的请求数。如果您同时收到两个请求,则计数可能不一致。
没有同步:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
包 组织.Arpit.爪哇2blog; 上市 类 RequestCounter { 私人的 整型 计数; 上市 整型 增量计数() { 计数++ ; 返回 计数; } } |
例如:
线程T1看到count为20并将其递增为21。同时,线程t2还将count为20并将其递增为21。这表明计数变得不一致。
使用同步:
您可以使用两种方法来实现同步。
- 同步方法
- 同步块
您不能与实例或类变量同步使用。
同步方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
包 组织.Arpit.爪哇2blog; 上市 类 RequestCounter { 私人的 整型 计数; 上市 已同步 整型 增量计数() { 计数++ ; 返回 计数; } } |
例如:
线程T1看到count为20,然后将其增加到21。同时,线程t2现在看到count为21,并将其增加到22。
同步块
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
包 组织.Arpit.爪哇2blog; 上市 类 RequestCounter { 私人的 整型 计数; 上市 整型 增量计数() { 已同步 (这个) { 计数++ ; 返回 计数; } } } |
例如:
线程T1的计数为20并将其递增为21。同时,线程t2现在将计数为21并将其递增为22。
爪哇中有两种锁定类型。
- 对象级锁定
- 类级别锁定
对象级别锁定:
使方法同步:
1 2 3 4 5 |
上市 已同步 整型 增量计数() { } |
使用同步块并对此进行锁定:
1 2 3 4 5 6 7 |
上市 整型 增量计数() { 已同步 (这个) { 计数++ ; 返回 计数; } |
使用同步块并锁定其他对象:
1 2 3 4 5 6 7 8 |
私人的 最后 目的 锁=新 目的(); 上市 整型 增量计数() { 已同步 (锁) { 计数++ ; 返回 计数; } |
类级别锁定:
这可以通过以下方式实现:
使静态方法同步:
1 2 3 4 5 |
上市 静态的 已同步 整型 增量计数() { } |
使用同步块并锁定.class:
1 2 3 4 5 6 7 |
上市 整型 增量计数() { 已同步 (RequestCounter.类) { 计数++ ; 返回 计数; } |
使用同步块并锁定其他静态对象:
1 2 3 4 5 6 7 8 |
私人的 最后 静态的 目的 锁=新 目的(); 上市 整型 增量计数() { 已同步 (锁) { 计数++ ; 返回 计数; } |
两个线程可以同时执行静态和非静态方法吗?
是的,由于两个线程将获得对不同对象的锁定,因此可以并发执行它们而不会出现任何问题。
如果一个类的方法是同步的,而同一类的其他方法是不同步的?它们可以由两个线程同时执行吗?
是的,因为一个线程需要锁才能进入同步块,而第二个线程将执行非同步方法’不需要任何锁定,因此可以并发执行。
从另一个同步方法调用同步方法是否安全?
是的,从另一个同步方法中调用同步方法是安全的,因为当您调用同步方法时,您将锁定 这个 对象,并且当您调用同一类的另一个同步方法时,可以安全执行,因为它已经锁定了 这个 目的。
例如:
1 2 3 4 5 6 7 8 9 10 |
上市 已同步 虚空 方法1() { 方法2(); //一些代码 } 上市 已同步 虚空 方法2() { //一些代码 } |
您实际上是在这样做。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
上市 虚空 方法1() { 已同步 (这个) { 方法2(); //一些代码 } } 上市 虚空 方法2() { 已同步 (这个) { //一些代码 } } |
在这里,如果有任何线程从method1调用method2,它将已经锁定 这个 对象,因此可以安全执行。