Synchronized 详解

同步是针对对象而言的,下面是错误示例
//class Foo extends Thread {
// private int val;
//
// public Foo(int v) {
// val = v;
// }
//
// public  void printVal(int v) {
// synchronized(this)
// {
// while (true)
// System.out.println(v);
// }
//
// }
//
// public void run() {
// printVal(val);
// }
//}
//运行结果是交替输入出1 3 ,因为以上代码看似加了同步锁,其实是对两个不同的对象加的。对同一个对象加锁才能实现同步


类同步不再对个别的类实例同步而是对类进行同步。对于类Foo而言,它只有唯一的类定义,两个线程在相同的锁上同步,因此只有一个线程可以执行printVal方法。
//class Foo extends Thread {
// private int val;
//
// public Foo(int v) {
// val = v;
// }
//
// public void printVal(int v) {
// synchronized (Foo.class) {
// while (true)
// System.out.println(v);
// }
// }
//
// public void run() {
// printVal(val);
// }
//}


// 这个代码也可以通过对公共对象加锁。例如给Foo添加一个静态成员。两个方法都可以同步这个对象而达到线程安全。
class Foo extends Thread {
private int val;
private  static Object lock=new Object();
public Foo(int v) {
val = v;
}


public void printVal(int v) {
synchronized (lock) {
while (true)
System.out.println(v);
}
}


public void run() {
printVal(val);
}
}


 上面这个代码需要进行一些额外的说明,因为JVM有一种优化机制,因为String类型的对象是不可变的,因此当你使用""的形式引用字符串时,如果JVM发现内存已经有一个这样的对象,那么它就使用那个对象而不再生成一个新的String对象,这样是为了减小内存的使用。
//class Foo extends Thread {
// private String name;
// private String val;
//
// public Foo(String name, String v) {
// this.name = name;
// val = v;
// }
//
// public void printVal() {
// synchronized (val) {
// while (true)
// System.out.println(name + val);
// }
// }
//
// public void run() {
// printVal();
// }
//}
//
//public class SyncTest {
// public static void main(String args[]) {
// Foo f1 = new Foo("Foo 1:", "printVal");
// f1.start();
// Foo f2 = new Foo("Foo 2:", "printVal");
// f2.start();
// }
//}


 public class SyncTest {
 public static void main(String args[]) {
 Foo f1 = new Foo(1);
 f1.start();
 Foo f2 = new Foo(3);
 f2.start();
 }
 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值