Synchronized
是Java中的关键字,是一种同步锁。他修饰的对象有以下几种。
- 修饰一个代码块
被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象。
- 修饰一个方法
被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象。
- 修饰一个静态方法
其作用的范围是整个静态方法,作用的对象是这个类的所有对象。
- 修饰一个类
其作用的范围是synchronized
后面括号括起来的部分,作用主的对象是这个类的所有对象。
修饰一个代码块
当修饰一个代码块时,我们一定要记住,作用的对象是调用
这个代码块的对象。我们下面通过一段代码看一下。
public class SynchronizedThread implements Runnable {
/**
* 计数
*/
private static int count;
@Override
public void run() {
synchronized (this) {
for (int i = 0; i < 5; i++) {
count++;
System.out.println(Thread.currentThread().getName() + ":" + count);
}
}
}
}
这段代码很简单,就是对对类的一个静态变量进行计数。
接下来我们看一下调用这段代码的地方。
SynchronizedThread synchronizedThread = new SynchronizedThread();
Thread thread1 = new Thread(synchronizedThread,"Thread1");
Thread thread2 = new Thread(synchronizedThread,"Thread2");
thread1.start();
thread2.start();
运行上面的代码,查看控制台的输出信息
不论我们怎么运行,Thead1
与Thread2
都是顺序执行的,这正是我们期望的。
接下来,我们对上面的代码稍微做一下改动,改动后如下
Thread thread3 = new Thread(new SynchronizedThread(),"Thread3");
Thread thread4 = new Thread(new SynchronizedThread(),"Thread4");
thread3.start();
thread4.start();
再次运行,查看控制台输出信息
可以看到Thead3
与Thread4
不再是顺序执行。
why?Synchronized
修饰一个代码块时,作用的对象是调用这个代码块的对象,我们可以看到Thead3
与Thread4
中是new
了一个新的对象,不再是同一个对象,所以Synchronized
不再起作用。
修饰一个方法
修饰一个方法跟修饰一个代码块类似,只是作用域不同。
我们继续修改SynchronizedThread
,修改后如下:
public class SynchronizedThread implements Runnable {
/**
* 计数
*/
private static int count;
@Override
public void run() {
increment();
}
public synchronized void increment(){
for (int i = 0; i < 15; i++) {
count++;
System.out.println(Thread.currentThread().getName() + ":" + count);
}
}
}
再次调用上面的两次代码,会发现结果是一样的。
修饰静态方法
由于静态方法是属于类而不是属于对象,因此synchronized
修饰的静态方法锁定的是这个类的所有对象。
我们再次对上面的SynchronizedThread
进行修改,将increment()
方法改成静态方法
public class SynchronizedThread implements Runnable {
/**
* 计数
*/
private static int count;
@Override
public void run() {
increment();
}
public synchronized static void increment(){
for (int i = 0; i < 15; i++) {
count++;
System.out.println(Thread.currentThread().getName() + ":" + count);
}
}
}
我们再次通过以下代码进行调用
Thread thread3 = new Thread(new SynchronizedThread(),"Thread3");
Thread thread4 = new Thread(new SynchronizedThread(),"Thread4");
thread3.start();
thread4.start();
查看控制台,可以看到之前不是顺序执行的方法,现在也是按照线程顺序执行了
修饰一个类
我们再次对上面的SynchronizedThread
进行修改
public class SynchronizedThread implements Runnable {
/**
* 计数
*/
private static int count;
@Override
public void run() {
increment();
}
public static void increment() {
synchronized (SynchronizedThread.class) {
for (int i = 0; i < 15; i++) {
count++;
System.out.println(Thread.currentThread().getName() + ":" + count);
}
}
}
}
我们再次通过以下代码进行调用
Thread thread3 = new Thread(new SynchronizedThread(),"Thread3");
Thread thread4 = new Thread(new SynchronizedThread(),"Thread4");
thread3.start();
thread4.start();
查看控制台,现在也是按照线程顺序执行的。
评论 (0)