synchronized关键字
Java提供了synchronized
关键字,用于控制台多线程同步。
可以加在方法上,在方法名前加synchronized
;
也可以加在一段代码块,synchronized (xxx) { ... }
,其中xxx为对象,一般为this, Xxx.class或者某个对象实例。
实例1
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
/**
* synchronized非static方法,多线程不同对象访问
* 并未同步执行
* 因为MyThread的run方法中new了不同的MySync对象
*
* @author cdfive
*/
public class SynchoronizedDemo1 {
public static void main(String[] args) {
int threadNum = 3;
for (int i = 0; i < threadNum; i++) {
MyThread myThread = new MyThread();
myThread.start();
}
}
static class MySync {
public synchronized void test() {
long start = System.currentTimeMillis();
System.out.println(String.format("%s start", Thread.currentThread().getName()));
try {
TimeUnit.SECONDS.sleep(ThreadLocalRandom.current().nextInt(3));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(String.format("%s end,cost=%dms", Thread.currentThread().getName(), (System.currentTimeMillis() - start)));
}
}
static class MyThread extends Thread {
@Override
public void run() {
MySync sync = new MySync();
sync.test();
}
}
}
实例2
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
/**
* 在非static方法里的synchronized this,多线程不同对象访问
* 并未同步执行
* 跟SynchoronizedDemo1类似,因为MyThread的run方法中new了不同的MySync对象
*
* @author cdfive
*/
public class SynchoronizedDemo2 {
public static void main(String[] args) {
int threadNum = 3;
for (int i = 0; i < threadNum; i++) {
MyThread myThread = new MyThread();
myThread.start();
}
}
static class MySync {
public void test() {
synchronized (this) {
long start = System.currentTimeMillis();
System.out.println(String.format("%s start", Thread.currentThread().getName()));
try {
TimeUnit.SECONDS.sleep(ThreadLocalRandom.current().nextInt(3));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(String.format("%s end,cost=%dms", Thread.currentThread().getName(), (System.currentTimeMillis() - start)));
}
}
}
static class MyThread extends Thread {
@Override
public void run() {
MySync sync = new MySync();
sync.test();
}
}
}
实例3
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
/**
* synchronized非static方法,多线程相同对象访问
* 同步执行成功
*
* @author cdfive
*/
public class SynchoronizedDemo3 {
public static void main(String[] args) {
int threadNum = 3;
MySync mySync = new MySync();
for (int i = 0; i < threadNum; i++) {
MyThread myThread = new MyThread(mySync);
myThread.start();
}
}
static class MySync {
public synchronized void test() {
long start = System.currentTimeMillis();
System.out.println(String.format("%s start", Thread.currentThread().getName()));
try {
TimeUnit.SECONDS.sleep(ThreadLocalRandom.current().nextInt(3));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(String.format("%s end,cost=%dms", Thread.currentThread().getName(), (System.currentTimeMillis() - start)));
}
}
static class MyThread extends Thread {
private MySync mySync;
public MyThread(MySync mySync) {
this.mySync = mySync;
}
@Override
public void run() {
mySync.test();
}
}
}
实例4
/**
* 在非static方法里的synchronized this,多线程相同对象访问
* 同步执行成功
*
* @author cdfive
*/
public class SynchoronizedDemo4 {
public static void main(String[] args) {
int threadNum = 3;
MySync mySync = new MySync();
for (int i = 0; i < threadNum; i++) {
MyThread myThread = new MyThread(mySync);
myThread.start();
}
}
static class MySync {
public synchronized void test() {
long start = System.currentTimeMillis();
System.out.println(String.format("%s start", Thread.currentThread().getName()));
try {
TimeUnit.SECONDS.sleep(ThreadLocalRandom.current().nextInt(3));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(String.format("%s end,cost=%dms", Thread.currentThread().getName(), (System.currentTimeMillis() - start)));
}
}
static class MyThread extends Thread {
private MySync mySync;
public MyThread(MySync mySync) {
this.mySync = mySync;
}
@Override
public void run() {
mySync.test();
}
}
}
实例5
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
/**
* 在非static方法里的synchronized Xxx.class,多线程不同对象访问
* 同步执行成功
* synchronized Xxx.class相当于全局锁
*
* @author cdfive
*/
public class SynchoronizedDemo5 {
public static void main(String[] args) {
int threadNum = 3;
for (int i = 0; i < threadNum; i++) {
MyThread myThread = new MyThread();
myThread.start();
}
}
static class MySync {
public void test() {
synchronized (SynchoronizedDemo5.class) {
long start = System.currentTimeMillis();
System.out.println(String.format("%s start", Thread.currentThread().getName()));
try {
TimeUnit.SECONDS.sleep(ThreadLocalRandom.current().nextInt(3));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(String.format("%s end,cost=%dms", Thread.currentThread().getName(), (System.currentTimeMillis() - start)));
}
}
}
static class MyThread extends Thread {
@Override
public void run() {
MySync sync = new MySync();
sync.test();
}
}
}
以上实例synchronized
同步方法,this,Xxx.class时,多线程使用相同或不同对象访问,有不同的结果,在日常开发中需要注意。