介绍synchronized关键字以前有必要阐述一下线程安全的概念。“非线程安全”会在多个线程对同一个对象中的实例变量进行并发访问时发生,产生的后果就是“脏读”,也就是取到的数据实际上是被更改过的,若是是方法内部的私有变量不存在“非线程安全”的问题;而“线程安全”就是得到的实例变量的值是通过同步处理的,不会出现脏读的现象。synchronized就是保证同步的。java
package chapter2.synch.method; public class MyObject { synchronized public void methodA() { try { System.out.println("begin methodA threadName="+Thread.currentThread().getName()+"--beginTime:"+System.currentTimeMillis()); Thread.sleep(5000); System.out.println("end methodA threadName="+Thread.currentThread().getName()+"--endTime:"+System.currentTimeMillis()); } catch (Exception e) { e.printStackTrace(); } } synchronized public void methodB() { try { System.out.println("begin methodB threadName="+Thread.currentThread().getName()+"--beginTime:"+System.currentTimeMillis()); Thread.sleep(2000); System.out.println("end methodB threadName="+Thread.currentThread().getName()+"--endTime:"+System.currentTimeMillis()); } catch (Exception e) { e.printStackTrace(); } } public void methodC() { try { System.out.println("begin methodC threadName="+Thread.currentThread().getName()+"--beginTime:"+System.currentTimeMillis()); Thread.sleep(2000); System.out.println("end methodC threadName="+Thread.currentThread().getName()+"--endTime:"+System.currentTimeMillis()); } catch (Exception e) { e.printStackTrace(); } } public void methodD() { try { synchronized (this) { System.out.println("begin methodD threadName="+Thread.currentThread().getName()+"--beginTime:"+System.currentTimeMillis()); Thread.sleep(2000); System.out.println("end methodD threadName="+Thread.currentThread().getName()+"--endTime:"+System.currentTimeMillis()); } } catch (Exception e) { e.printStackTrace(); } } public void methodE() { try { Object object = new Object(); synchronized (object) { System.out.println("begin methodE threadName="+Thread.currentThread().getName()+"--beginTime:"+System.currentTimeMillis()); Thread.sleep(2000); System.out.println("end methodE threadName="+Thread.currentThread().getName()+"--endTime:"+System.currentTimeMillis()); } } catch (Exception e) { e.printStackTrace(); } } public void methodF(Object object) { try { synchronized (object) { System.out.println("begin methodF threadName="+Thread.currentThread().getName()+"--beginTime:"+System.currentTimeMillis()); Thread.sleep(2000); System.out.println("end methodF threadName="+Thread.currentThread().getName()+"--endTime:"+System.currentTimeMillis()); } } catch (Exception e) { e.printStackTrace(); } } }
package chapter2.synch.method; public class ThreadA extends Thread{ private MyObject myObject; public MyObject getMyObject() { return myObject; } public void setMyObject(MyObject myObject) { this.myObject = myObject; } @Override public void run() { super.run(); myObject.methodA(); } } package chapter2.synch.method; public class ThreadB extends Thread{ private MyObject myObject; public MyObject getMyObject() { return myObject; } public void setMyObject(MyObject myObject) { this.myObject = myObject; } @Override public void run() { super.run(); myObject.methodB(); } } package chapter2.synch.method; public class Run { public static void main(String[] args) { MyObject myObject = new MyObject(); ThreadA threadA = new ThreadA(); threadA.setMyObject(myObject); threadA.setName("A"); ThreadB threadB = new ThreadB(); threadB.setMyObject(myObject); threadB.setName("B"); threadA.start(); threadB.start(); } }
运行结果:(同步执行)安全
begin methodA threadName=A--beginTime:1560936665128
end methodA threadName=A--endTime:1560936670128
begin methodB threadName=B--beginTime:1560936670128
end methodB threadName=B--endTime:1560936672128并发
若是ThreadB 修改为myObject.methodC();异步
运行结果:(异步执行)ide
begin methodC threadName=B--beginTime:1560936788821
begin methodA threadName=A--beginTime:1560936788821
end methodC threadName=B--endTime:1560936790821
end methodA threadName=A--endTime:1560936793821this
若是ThreadB 修改为myObject.methodD();spa
运行结果:(同步执行)线程
begin methodD threadName=B--beginTime:1560936856169
end methodD threadName=B--endTime:1560936858169
begin methodA threadName=A--beginTime:1560936858169
end methodA threadName=A--endTime:1560936863169
code
若是ThreadB 修改为myObject.methodE();对象
运行结果:(异步执行)
begin methodE threadName=B--beginTime:1560936949062
begin methodA threadName=A--beginTime:1560936949062
end methodE threadName=B--endTime:1560936951062
end methodA threadName=A--endTime:1560936954062
代码作以下修改:
package chapter2.synch.method; public class ThreadA extends Thread{ private MyObject myObject; private Object object; public Object getObject() { return object; } public void setObject(Object object) { this.object = object; } public MyObject getMyObject() { return myObject; } public void setMyObject(MyObject myObject) { this.myObject = myObject; } @Override public void run() { super.run(); myObject.methodF(object); } }
package chapter2.synch.method;
public class Run {
public static void main(String[] args) {
MyObject myObject = new MyObject();
Object object = new Object();
ThreadA threadA = new ThreadA();
threadA.setObject(object);
threadA.setMyObject(myObject);
threadA.setName("A");
ThreadA threadB = new ThreadA();
threadB.setMyObject(myObject);
threadB.setObject(object);
threadB.setName("B");
threadA.start();
threadB.start();
}
}
运行结果:(同步执行)
begin methodF threadName=A--beginTime:1560937583035
end methodF threadName=A--endTime:1560937585035
begin methodF threadName=B--beginTime:1560937585035
end methodF threadName=B--endTime:1560937587035
结论:对象锁。
若是synchronized加到static方法上是给Class类上锁,Class锁能够对类的全部实例对象起做用。
特色: