JAva同時(二):syncronizedの初期プローブ
ブログ参照
Javaマルチスレッドシリーズ–「基礎編」04のsynchronizedキーワード
synchronized基本規則
第一条
スレッドがAオブジェクトのsynchronizedメソッドと同期ブロックにアクセスすると、他のスレッドはAオブジェクトのsynchronizedメソッドと同期ブロックにアクセスできません.
第二条
スレッドがAオブジェクトのsynchronizedメソッドと同期ブロックにアクセスすると、他のスレッドはAオブジェクトの非synchronizedメソッドと同期ブロックにアクセスできます.
第三条
スレッドがAオブジェクトのsynchronizedメソッドと同期ブロックにアクセスする場合、他のスレッドはAオブジェクトの他のsynchronizeddメソッドと同期ブロックにアクセスできますか?
第三条基本原則テスト
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class SysDemo3 {
public static void main(String[] args) {
final Count count =new Count();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
count.synMethodA();
}
},"t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
count.synMethodB();
}
},"t2");
t1.start();
t2.start();
}
}
@Slf4j
class Count {
int countsize =5;
public synchronized void synMethodA(){
int count =0;
while(count<countsize){
log.info("synMethodA, Current thread is : {}, count = {}",Thread.currentThread().getName(),count++);
}
}
public synchronized void synMethodB(){
int count =0;
while(count<countsize){
log.info("synMethodB, Current thread is : {}, count = {}",Thread.currentThread().getName(),count++);
}
}
}
テスト結果
2019-07-25 13:40:44,482 [t1] INFO Count - synMethodA, Current thread is : t1, count = 0
2019-07-25 13:40:44,482 [t1] INFO Count - synMethodA, Current thread is : t1, count = 1
2019-07-25 13:40:44,482 [t1] INFO Count - synMethodA, Current thread is : t1, count = 2
2019-07-25 13:40:44,482 [t1] INFO Count - synMethodA, Current thread is : t1, count = 3
2019-07-25 13:40:44,482 [t1] INFO Count - synMethodA, Current thread is : t1, count = 4
2019-07-25 13:40:44,482 [t2] INFO Count - synMethodB, Current thread is : t2, count = 0
2019-07-25 13:40:44,482 [t2] INFO Count - synMethodB, Current thread is : t2, count = 1
2019-07-25 13:40:44,482 [t2] INFO Count - synMethodB, Current thread is : t2, count = 2
2019-07-25 13:40:44,482 [t2] INFO Count - synMethodB, Current thread is : t2, count = 3
2019-07-25 13:40:44,482 [t2] INFO Count - synMethodB, Current thread is : t2, count = 4
説明
各オブジェクトには同期ロックがあり、同期ロックはオブジェクトに依存して存在します.以上の結果は、Aオブジェクトの同期方法または同期ブロックが呼び出された場合、このロックはユーザにあり、他のユーザがAオブジェクトの同期方法または同期ブロックを呼び出す場合、ロックは取得されないことを示している.
インスタンス・ロックとグローバル・ロック
インスタンス・ロックはオブジェクトにロックされますグローバル・ロックはクラスにロックされますstatic syncronizedメソッドまたは同期ブロック
異なるスレッドは、クラスの異なるstatic syncronizedメソッドを呼び出します。
異なるスレッドはクラスの異なるstatic syncronizedメソッドを呼び出します:x.classSyn 1()とy.classSyn 2()、xは解放されず、yは静的同期メソッドを実行できません.
テスト
import lombok.extern.slf4j.Slf4j;
import static java.lang.Thread.sleep;
/*
, static syncronized ,
,
*/
@Slf4j
public class SysDemo5 {
static class Count {
static int countsize =5;
public synchronized void synMethodA(){
int count =0;
while(count<countsize){
log.info("synMethodA, Current thread is : {}, count = {}",Thread.currentThread().getName(),count++);
try {
sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void synMethodB(){
int count =0;
while(count<countsize){
log.info("synMethodB, Current thread is : {}, count = {}",Thread.currentThread().getName(),count++);
try {
sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static synchronized void cSynMethodA(){
int count =0;
while(count<countsize){
log.info("class synMethodA, Current thread is : {}, count = {}",Thread.currentThread().getName(),count++);
try {
sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static synchronized void cSynMethodB(){
int count =0;
while(count<countsize){
log.info("class synMethodB, Current thread is : {}, count = {}",Thread.currentThread().getName(),count++);
try {
sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
Count.cSynMethodA();
}
},"t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
Count.cSynMethodB();
}
},"t2");
t1.start();
t2.start();
}
}
テスト結果
2019-07-25 17:31:24,358 [t1] INFO SysDemo5 - class synMethodA, Current thread is : t1, count = 0
2019-07-25 17:31:24,857 [t1] INFO SysDemo5 - class synMethodA, Current thread is : t1, count = 1
2019-07-25 17:31:25,356 [t1] INFO SysDemo5 - class synMethodA, Current thread is : t1, count = 2
2019-07-25 17:31:25,855 [t1] INFO SysDemo5 - class synMethodA, Current thread is : t1, count = 3
2019-07-25 17:31:26,354 [t1] INFO SysDemo5 - class synMethodA, Current thread is : t1, count = 4
2019-07-25 17:31:26,853 [t2] INFO SysDemo5 - class synMethodB, Current thread is : t2, count = 0
2019-07-25 17:31:27,351 [t2] INFO SysDemo5 - class synMethodB, Current thread is : t2, count = 1
2019-07-25 17:31:27,850 [t2] INFO SysDemo5 - class synMethodB, Current thread is : t2, count = 2
2019-07-25 17:31:28,349 [t2] INFO SysDemo5 - class synMethodB, Current thread is : t2, count = 3
2019-07-25 17:31:28,847 [t2] INFO SysDemo5 - class synMethodB, Current thread is : t2, count = 4
x.classSyn 1とx.sysn 1
オブジェクトの同期メソッドとクラスの同期メソッドは互いに影響しません
テスト
import lombok.extern.slf4j.Slf4j;
import static java.lang.Thread.sleep;
@Slf4j
public class SysDemo4 {
static class Count {
static int countsize =5;
public synchronized void synMethodA(){
int count =0;
while(count<countsize){
log.info("synMethodA, Current thread is : {}, count = {}",Thread.currentThread().getName(),count++);
try {
sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void synMethodB(){
int count =0;
while(count<countsize){
log.info("synMethodB, Current thread is : {}, count = {}",Thread.currentThread().getName(),count++);
try {
sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static synchronized void cSynMethodA(){
int count =0;
while(count<countsize){
log.info("class synMethodA, Current thread is : {}, count = {}",Thread.currentThread().getName(),count++);
try {
sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
final Count count =new Count();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
count.synMethodA();
}
},"t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
Count.cSynMethodA();
}
},"t2");
t1.start();
t2.start();
}
}
テスト結果
2019-07-25 19:04:53,184 [t2] INFO SysDemo4 - class synMethodA, Current thread is : t2, count = 0
2019-07-25 19:04:53,199 [t1] INFO SysDemo4 - synMethodA, Current thread is : t1, count = 0
2019-07-25 19:04:53,683 [t2] INFO SysDemo4 - class synMethodA, Current thread is : t2, count = 1
2019-07-25 19:04:53,699 [t1] INFO SysDemo4 - synMethodA, Current thread is : t1, count = 1
2019-07-25 19:04:54,182 [t2] INFO SysDemo4 - class synMethodA, Current thread is : t2, count = 2
2019-07-25 19:04:54,198 [t1] INFO SysDemo4 - synMethodA, Current thread is : t1, count = 2
2019-07-25 19:04:54,682 [t2] INFO SysDemo4 - class synMethodA, Current thread is : t2, count = 3
2019-07-25 19:04:54,697 [t1] INFO SysDemo4 - synMethodA, Current thread is : t1, count = 3
2019-07-25 19:04:55,181 [t2] INFO SysDemo4 - class synMethodA, Current thread is : t2, count = 4
2019-07-25 19:04:55,197 [t1] INFO SysDemo4 - synMethodA, Current thread is : t1, count = 4
Process finished with exit code 0