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获得的锁是可以重入的,子类也可以调用父类的同步方法