同步方法
Posted pxy-1999
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了同步方法相关的知识,希望对你有一定的参考价值。
public class SellTickets implements Runnable{ //共有100张票 private int tickets = 100; private Object obj = new Object(); private int x = 0; @Override public void run() { while (true) { //锁多条语句操作共享数据,当线程1运行进入锁时,对外相当于被锁起来,其他线程只能等待线程1运行结束才能进入。 if (x % 2 == 0) { synchronized (obj) { if (tickets > 0) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票"); tickets--; } } } else { synchronized (obj) { if (tickets > 0) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票"); tickets--; } } } x++; } } }
将上述代码中else部分使用一个单独的方法并加锁来实现:
private synchronized void SellTicket() {
if (tickets > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");
tickets--;
}
}
此时来运行卖票测试类:
此时仍然会发生数据安全问题,原因在于synchronized关键字在锁方法时,锁的是一个方法,其对应的对象应该能表示本方法的——this,而在if中锁的对象仍然还是Object,所以会发生问题,将if语句中锁的对象修改为this后的代码:
synchronized (this) { if (tickets > 0) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票"); tickets--; }
此时的运行结果:
没有出现数据安全问题
那么如果我将synchronized加到静态方法上,锁对应的对象应该是什么?
分析staic关键字可以猜到,锁静态方法时,应该是要锁一个与类相关的对象——类名.class(字节码文件)
public class SellTickets implements Runnable{ //共有100张票 private static int tickets = 100; private Object obj = new Object(); private int x = 0; @Override public void run() { while (true) { //锁多条语句操作共享数据,当线程1运行进入锁时,对外相当于被锁起来,其他线程只能等待线程1运行结束才能进入。 if (x % 2 == 0) { synchronized (SellTickets.class) { if (tickets > 0) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票"); tickets--; } } } else { SellTicket(); } x++; } } private static synchronized void SellTicket() { if (tickets > 0) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票"); tickets--; } } }
运行结果也是没有问题的。
以上是关于同步方法的主要内容,如果未能解决你的问题,请参考以下文章
[工作积累] UE4 并行渲染的同步 - Sync between FParallelCommandListSet & FRHICommandListImmediate calls(代码片段