synchronized是java中最常用的一种锁机制,本篇文章主要介绍他的两种用途:类锁和对象锁。
关于synchronized的更多内容可以查看这篇文章: Java-并发-锁-synchronized
更多关于Java锁的信息,可参考文章:Java-并发-关于锁的一切
几张图片转自图解Java多线程,作者 任何忧伤,都抵不过世界的美丽
synchronized
作为对象锁时,用在非静态方法或非静态对象上,下面是示例:
/**
* 对象锁
*/
public synchronized void nonStaticMethodLock(){
for(int i = 0 ; i< 5 ; i++){
System.out.println(Thread.currentThread().getName()+" nonStaticMethodLock");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* 对象锁
*/
public void objectLock(){
synchronized(this){
for(int i = 0 ; i< 5 ; i++){
System.out.println(Thread.currentThread().getName()+" objectLock");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
类锁修饰方法、代码块的效果和对象锁是一样的,因为类锁只是一个抽象出来的概念,只是为了区别静态方法的特点。因为静态方法是所有对象实例共用的,所以对应synchronized修饰的静态方法的锁也是唯一的,所以抽象出来个类锁。
下面是代码示例:
/**
* 类锁
*/
public void classLock(){
synchronized(Test3.class){
for(int i = 0 ; i< 5 ; i++){
System.out.println(Thread.currentThread().getName()+" classLock");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**
* 类锁
*/
public static synchronized void staticMethodLock(){
for(int i = 0 ; i< 5 ; i++){
System.out.println(Thread.currentThread().getName()+" staticMethodLock");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
下面是完整的代码示例,可以自行调试观察结果,加深理解:
package demos.concurrent.thread.synchronizedTest.objectAndMethodLock;
/**
* Created by chengc on 2018/10/22.
*/
public class Test3 {
private Object nonStaticLockObj = new Object();
private static Object staticLockObj = new Object();
private static Object staticLockObj2 = new Object();
/**
* 类锁
*/
public void classLock(){
synchronized(Test3.class){
for(int i = 0 ; i< 5 ; i++){
System.out.println(Thread.currentThread().getName()+" classLock");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**
* 类锁
*/
public static synchronized void staticMethodLock(){
for(int i = 0 ; i< 5 ; i++){
System.out.println(Thread.currentThread().getName()+" staticMethodLock");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void ordinaryMethod(){
for(int i = 0 ; i< 5 ; i++){
System.out.println(Thread.currentThread().getName()+" ordinaryMethod");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* 对象锁
*/
public synchronized void nonStaticMethodLock(){
for(int i = 0 ; i< 5 ; i++){
System.out.println(Thread.currentThread().getName()+" nonStaticMethodLock");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* 对象锁
*/
public void thisObjectLock(){
synchronized(this){
for(int i = 0 ; i< 5 ; i++){
System.out.println(Thread.currentThread().getName()+" thisObjectLock");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**
* 对象锁
*/
public void nonStaticObjectLock(){
synchronized(nonStaticLockObj){
for(int i = 0 ; i< 5 ; i++){
System.out.println(Thread.currentThread().getName()+" nonStaticLockObj");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**
* 对象锁
*/
public void staticObjectLock(){
synchronized(staticLockObj){
for(int i = 0 ; i< 5 ; i++){
System.out.println(Thread.currentThread().getName()+" staticLockObj");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**
* 对象锁
*/
public void staticObjectLock2(){
synchronized(staticLockObj2){
for(int i = 0 ; i< 5 ; i++){
System.out.println(Thread.currentThread().getName()+" staticLockObj2");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
Test3 test1 = new Test3();
new Thread(new Runnable() {
@Override
public void run() {
test1.classLock();
}
},"Thread1").start();
new Thread(new Runnable() {
@Override
public void run() {
test1.nonStaticMethodLock();
}
},"Thread2").start();
new Thread(new Runnable() {
@Override
public void run() {
test1.ordinaryMethod();
}
},"Thread3").start();
new Thread(new Runnable() {
@Override
public void run() {
test1.staticMethodLock();
}
},"Thread4").start();
new Thread(new Runnable() {
@Override
public void run() {
test1.thisObjectLock();
}
},"Thread5").start();
new Thread(new Runnable() {
@Override
public void run() {
test1.nonStaticObjectLock();
}
},"Thread6").start();
new Thread(new Runnable() {
@Override
public void run() {
test1.staticObjectLock();
}
},"Thread7").start();
new Thread(new Runnable() {
@Override
public void run() {
test1.staticObjectLock2();
}
},"Thread8").start();
}
}
通过以上代码调试,总结如下:
this
修饰的对象锁同时只能有一个线程进入执行,但不影响其他方法执行XXX.class
修饰的为类锁,同时只能有一个线程进入执行,但不影响其他方法执行关于synchronized的更多内容可以查看这篇文章: Java-并发-锁-synchronized
更多关于Java锁的信息,可参考文章:Java-并发-关于锁的一切