Java中获取锁有两种方式,一种是使用synchronized关键字,另外一种就是使用Lock接口的实现类。 本文重点讲 synchronized
synchronized是Java中的关键字,是一种同步锁。它修饰的对象有以下几种:
1. 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象;
2. 修饰一个方法,被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的象;
3. 修改一个静态的方法,其作用的范围是整个静态方法,作用的对象是这个类的所有对象;
4. 修改一个类,其作用的范围是synchronized后面括号括起来的部分,作用主的对象是这个类的所有对象。
5. 类锁和对象锁是两个不一样的锁,控制着不同的区域,它们是互不干扰的。同样,线程获得对象锁的同时,也可以获得该类锁,即同时获得两个锁。
就是说,不同线程可以同时访问加了对象锁和类锁的方法
public class SynchronizedTest {
/**
* synchronized (this) 锁住代码块,锁的是当前对象
*/
public void test1() {
synchronized (this) {
int i = 5;
while (i-- > 0) {
System.out.println(Thread.currentThread().getName() + " : " + i);
sleepFuc(500);
}
}
}
/**
* synchronized加在成员方法上锁的是当前对象,等价于 synchronized (this)
*/
public synchronized void test2() {
int i = 5;
while (i-- > 0) {
System.out.println(Thread.currentThread().getName() + " : " + i);
sleepFuc(500);
}
}
/**
* 非同步方法
*/
public void test3() {
int i = 5;
while (i-- > 0) {
System.out.println(Thread.currentThread().getName() + " : " + i);
sleepFuc(500);
}
}
/**
* synchronized用在静态方法上是类锁方法等价于 synchronized (SynchronizedTest.class)
*/
public static synchronized void test4() {
int i = 5;
while (i-- > 0) {
System.out.println(Thread.currentThread().getName() + " : " + i);
try {
Thread.sleep(500);
} catch (InterruptedException ie) {
}
}
}
/**
* 类锁方法
*/
public void test5() {
synchronized (SynchronizedTest.class) {
int i = 5;
while (i-- > 0) {
System.out.println(Thread.currentThread().getName() + " : " + i);
sleepFuc(500);
}
}
}
private void sleepFuc(int mill) {
try {
Thread.sleep(mill);
} catch (InterruptedException ie) {
}
}
public static void main(String[] args) {
final SynchronizedTest test = new SynchronizedTest();
// Thread test1 = new Thread(test::test1, "synchronized (this)");
Thread test2 = new Thread(test::test2, "synchronized method");
// Thread test3 = new Thread(test::test3, "not synchronized");
Thread test4 = new Thread(SynchronizedTest::test4, "static synchronized method");
// Thread test5 = new Thread(test::test5, " synchronized (SynchronizedTest.class)");
// test1.start();
test2.start();
// test3.start();
test4.start();
// test5.start();
}
/*
* 非静态方法:
* 给对象加锁(可以理解为给这个对象的内存上锁,注意 只是这块内存,其他同类对象都会有各自的内存锁),这时- * 候 在其他一个以上线程中执行该对象的这个同步方法(注意:是该对象)就会产生互斥
* 静态方法:
* 相当于在类上加锁(*.class 位于代码区,静态方法位于静态区域,这个类产生的对象公用这个静态方法,所以这块 * 内存,N个对象来竞争), 这时候,只要是这个类产生的对象,在调用这个静态方法时都会产生互斥
*/
}