正文
java之结合代码理解synchronized关键字
小程序:扫一扫查出行
【扫一扫了解最新限行尾号】
复制小程序
【扫一扫了解最新限行尾号】
复制小程序
为了保证数据的一致性即实现线程的安全性,java虚拟机提供了同步和锁机制。synchronized关键字是最基本的互斥同步手段。除此之外,还可以使用java.util.concurrent包中的重入锁(ReentrantLock)来实现同步。相比synchronized,ReentrantLock增加了一些高级功能,主要有等待可中断、可实现公平锁、锁可以绑定多个条件等。
见SynchronizedDemo.java的源码理解synchronized
/**
* Synchronized理解:
* 根据如下4个例子总结如下:
* Synchronized修饰的方法和Synchronized(this)修饰的代码块功能是一样的,当使用Synchronized修饰的方法或Synchronized(this)修饰的代码块被调用时,当前的实例对象被锁住,因此没有其他线程可以调用该实例对象的这个或任何其他的Synchronized修饰的方法和Synchronized(this)修饰的代码块
* static Synchronized修饰的方法和Synchronized(*.class)修饰的代码块功能是一样的,当使用static Synchronized修饰的方法或Synchronized(*.class)修饰的代码块被调用时,当前的类对象(例子中的是Sync.class对象)被锁住,因此没有其他线程可以调用同一个类的的这个或任何其他的static Synchronized修饰的方法和Synchronized(*.class)修饰的代码块
**/
public class SynchronizedDemo{
/**
* 例1:
* 同一个对象:
* 当一个线程进入一个对象A的synchronized方法的同时,其它线程不能进入该对象的任何synchronized方法
**/
private void showSynchronizedResult1(){
final Sync testSync1 = new Sync(); Thread thread1 = new Thread(new Runnable(){
@Override
public void run(){
testSync1.run1();
}
}); Thread thread2 = new Thread(new Runnable(){
@Override
public void run(){
testSync1.run2();
}
}); thread1.start();
thread2.start();
} /**
* 例2:
* 同一个对象:
* 当一个线程进入一个对象A的synchronized方法的同时,其它线程可以进入该对象的普通方法
**/
private void showSynchronizedResult2(){
final Sync testSync1 = new Sync(); Thread thread1 = new Thread(new Runnable(){
@Override
public void run(){
testSync1.run1();
}
}); Thread thread3 = new Thread(new Runnable(){
@Override
public void run(){
testSync1.run3();
}
}); thread1.start();
thread3.start();
} /**
* 例3:
* 不同对象
* 当一个线程进入一个对象A的synchronized方法的同时,其它线程可以进入其他对象的synchronized方法,互不影响
**/
private void showSynchronizedResult3(){
final Sync testSync1 = new Sync();
final Sync testSync2 = new Sync(); Thread thread1 = new Thread(new Runnable(){
@Override
public void run(){
testSync1.run1();
}
}); Thread thread2 = new Thread(new Runnable(){
@Override
public void run(){
testSync2.run2();
}
}); thread1.start();
thread2.start();
} /**
* 例4:
* 当一个线程进入一个static synchronized方法的同时,其它线程不可以进入任何的static synchronized方法
**/
private void showStaticSynchronizedResult4(){
Thread thread1 = new Thread(new Runnable(){
@Override
public void run(){
Sync.run4();
}
}); Thread thread2 = new Thread(new Runnable(){
@Override
public void run(){
Sync.run5();
}
}); thread1.start();
thread2.start();
} public static void main(String args[]){
// 例1:多线程下同一对象的多个Synchronized方法
new SynchronizedDemo().showSynchronizedResult1(); // 例2:多线程下同一对象的Synchronized方法和普通方法
//new SynchronizedDemo().showSynchronizedResult2(); // 例3:多线程下不同对象的Synchronized方法
//new SynchronizedDemo().showSynchronizedResult3(); // 例4:多线程下的多个static Synchronized方法
//new SynchronizedDemo().showStaticSynchronizedResult4();
}
}class Sync{
public synchronized void run1(){
for (int i = 0; i < 5; i++){
System.out.println("execute run1");
sleepOneSec();
}
} public synchronized void run2(){
for (int i = 0; i < 5; i++){
System.out.println("execute run2");
sleepOneSec();
}
} public void run3(){
for (int i = 0; i < 5; i++){
System.out.println("execute run3");
sleepOneSec();
}
} public static synchronized void run4(){
for (int i = 0; i < 5; i++){
System.out.println("execute run4");
sleepOneSec();
}
} public static synchronized void run5(){
for (int i = 0; i < 5; i++){
System.out.println("execute run5");
sleepOneSec();
}
} private static void sleepOneSec(){
try{
Thread.sleep(1000);
}catch (InterruptedException e){
e.printStackTrace();
}
}
}