1.同步方法和非同步方法是否可以同时调用
可以同时调用,可以理解为不加synchronized的方法无视这个对象的锁
int count=10;
public synchronized void m1(){
count--;
System.out.println(Thread.currentThread().getName()+"m1 started 01 : "+count);
try {
Thread.sleep(10000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"m1 started 02 : "+count);
}
public /*synchronized*/ void m2(){
try {
count--;
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"m2 start ..."+count);
}
public static void main(String[] args) {
Test t = new Test();
new Thread(()->t.m1(),"m1").start();
new Thread(()->t.m2(),"m2").start();
}
2.对业务写方法上枷锁,业务读方法上不加锁,可能会产生脏读现象(读到在写的过程中还没有完成的数据)
String name;
Double price;
public synchronized void set(String name,Double price){
this.name=name;
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.price=price;
}
public Double get(){
return this.price;
}
public static void main(String[] args) {
Test t = new Test();
new Thread(()->t.set("zhangsan",100.00),"m1").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(t.get());
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(t.get());
}
3.一个同步方法可以调用另外一个同步方法,
一个线程已经拥有了某个对象的锁,再次申请的时候仍然会得到该对象的锁,也就是说synchronized获得的锁是可以重入的,子类也可以调用父类的同步方法