シンクロナイズド
Javaはアイデアをプログラミングしない:各オブジェクトは(また、「モニター」と呼ばれる)のロックが含まれ、それが自動的にオブジェクトの一部になり、任意の同期メソッドを呼び出して、オブジェクトがロックされ、もはや他のコールのオブジェクトがあること第1の方法は、自分の仕事を完了し、ロックを解除しない限り、メソッドを同期。
特長:JVMレベル、不公平、悲観的、排他的、リエントラント、ヘビー級。
処置:コードブロックおよび方法を変更します。
コードブロックを修正する方法および
同期変更静的メソッド、我々は、つまり、「ロック」、それを呼び出すことができます限り、スレッドインスタンスオブジェクトがロックを取得するがあるとして、対象物の他のスレッドのインスタンスは待つ必要があります。同じクラスが呼び出すことができるの下に別のスレッド同期メソッドのインスタンスオブジェクトである我々は、オブジェクトのロックを呼び出す非静的メソッドの変更は、あります。
/**
* @PackageName com.a.squirrel.synchronize
* @Author: squirrel
* @Date: 2018/6/25 10:04
* @Description: synchronized解析辅助类
*/
public class SynchronizedDescription {
private String tmpStr;
private int tmpInt;
/**
* @Author squirrel
* @Description 非静态同步方法
* @Date 2018/6/25
* @Param [synchronizedDescription]
* @return
**/
public synchronized void testSynchronizedMethod(SynchronizedDescription synchronizedDescription){
System.out.println("线程:"+synchronizedDescription.getTmpInt()+"-->:==========我是非静态同步方法=======");
System.out.println("线程:"+synchronizedDescription.getTmpInt()+"-->:调用非静态同步方法时间为:"+getNowTime());
try {
Thread.sleep(5000);// 当前线程休眠5s,休眠过程中不会释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* @Author squirrel
* @Description 同步代码块
* @Date 2018/6/25
* @Param [synchronizedDescription]
* @return
**/
public void testSynchronizedBlockMethod(SynchronizedDescription synchronizedDescription){
synchronized (synchronizedDescription){// 锁定实例对象
System.out.println("线程:"+synchronizedDescription.getTmpInt()+"-->:==========我是同步代码块=======");
System.out.println("线程:"+synchronizedDescription.getTmpInt()+"-->:调用同步代码块时间为:"+getNowTime());
try {
Thread.sleep(2000);// 当前线程休眠2s,休眠过程中不会释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* @Author squirrel
* @Description 静态同步方法
* @Date 2018/6/25
* @Param [synchronizedDescription]
* @return
**/
public synchronized static void testSynchronizedStaticMethod(SynchronizedDescription synchronizedDescription){
System.out.println("线程:"+synchronizedDescription.getTmpInt()+"-->:==========我是静态同步方法=======");
System.out.println("线程:"+synchronizedDescription.getTmpInt()+"-->:调用静态同步方法时间为:"+getNowTime());
try {
Thread.sleep(10000);// 当前线程休眠10s,休眠过程中不会释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* @Author squirrel
* @Description 获取当前时间
* @Date 2018/6/25
* @Param []
* @return java.lang.String
**/
private static String getNowTime(){
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
}
public SynchronizedDescription(String tmpStr, int tmpInt) {
this.tmpStr = tmpStr;
this.tmpInt = tmpInt;
}
public String getTmpStr() {
return tmpStr;
}
public void setTmpStr(String tmpStr) {
this.tmpStr = tmpStr;
}
public int getTmpInt() {
return tmpInt;
}
public void setTmpInt(int tmpInt) {
this.tmpInt = tmpInt;
}
}
/**
* @PackageName com.a.squirrel.synchronize
* @Author: squirrel
* @Date: 2018/6/25 10:10
* @Description: 测试类
*/
public class TestSynchronized {
public static void main(String[] args) {
// 创建阻塞队列
final BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(100);
// 创建线程池
final ThreadPoolExecutor threadPool = new ThreadPoolExecutor(2,20,60, TimeUnit.SECONDS,queue);
threadPool.allowCoreThreadTimeOut(true);
for (int i =0;i<100;i++){
threadPool.execute(new Runnable() {
@Override
public void run() {
final String tmpStr = Thread.currentThread().getName();
final String[] split = tmpStr.split("-");
int tmpInt = Integer.parseInt(split[split.length-1]);
SynchronizedDescription synchronizedDescription = new SynchronizedDescription(tmpStr,tmpInt);
// 调用同步代码块
synchronizedDescription.testSynchronizedBlockMethod(synchronizedDescription);
// 调用非静态同步方法
synchronizedDescription.testSynchronizedMethod(synchronizedDescription);
// 调用静态同步方法
synchronizedDescription.testSynchronizedStaticMethod(synchronizedDescription);
}
});
}
}
}
業績は上記の結論を確認することができます
のは、同期オブジェクトの同期コードブロックを変更してみましょう:
/**
* @Author squirrel
* @Description 同步代码块
* @Date 2018/6/25
* @Param [synchronizedDescription]
* @return
**/
public void testSynchronizedBlockMethod(SynchronizedDescription synchronizedDescription){
synchronized (SynchronizedDescription.class){// 锁定类对象
System.out.println("线程:"+synchronizedDescription.getTmpInt()+"-->:==========我是同步代码块=======");
System.out.println("线程:"+synchronizedDescription.getTmpInt()+"-->:调用同步代码块时间为:"+getNowTime());
try {
Thread.sleep(2000);// 当前线程休眠2s,休眠过程中不会释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
上記のグラフから、我々はこの結論を説明するための図を借り、ここで、結論を引き出すことができます。
原則:
Java仮想マシンの深い理解第一オブジェクト、インスタンスデータ、およびアライメントパディング:メモリ・レイアウトに記憶されたオブジェクトは、3つの領域に分割されてもよいです。
同期オブジェクトロックは、各インスタンスは、あなたが一緒にオブジェクトを作成し、破壊することができます監視され、モニターを持って、あなたはまた、スレッド、自動的に生成されたオブジェクトのロックを取得しようとすることができ、そのモニタオブジェクトへのポインタです。monitorenter命令の実装では、オブジェクトがロックされていない場合、我々は最初に、オブジェクトのロックを取得しようとしなければならない、または現在のスレッドがすでにオブジェクトのロックを所有している、その後、命令実行monitorexitは、ロックカウンタしばらくのロックを解除する際にロックカウンタがインクリメントされ置きますマイナス1になります。