在平常的开发中多线程肯定是离不开的,而线程同步中有一个很重要的概念就是synchronize。下面我就会对这个关键字进行发表一点我的理解。
synchronize是一种同步锁,他可以有以下几种用法
- 修饰普通方法
- 修饰静态方法
- 修饰代码块
当普通方法被synchronize修饰的时候该对象就被锁住了
public class SynchronizeDemo {
private int num = 0;
synchronized public void add(){
for (int i = 0; i < 5; i++){
System.out.println(Thread.currentThread().getName() + "----" + (num++));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args){
final SynchronizeDemo synchronizeDemo = new SynchronizeDemo();
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
synchronizeDemo.add();
}
},"test1");
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
synchronizeDemo.add();
}
},"test2");
thread.start();
thread2.start();
}
这时就会输出
test1----0
test1----1
test1----2
test1----3
test1----4
test2----5
test2----6
test2----7
test2----8
test2----9
但是像下面这样
public static void main(String[] args){
final SynchronizeDemo synchronizeDemo1 = new SynchronizeDemo();
final SynchronizeDemo synchronizeDemo2 = new SynchronizeDemo();
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
synchronizeDemo1.add();
}
},"test1");
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
synchronizeDemo2.add();
}
},"test2");
thread.start();
thread2.start();
}
就会输出
test1----0
test2----0
test2----1
test1----1
test1----2
test2----2
test1----3
test2----3
test2----4
test1----4
这是当然的因为synchronize修饰方法时他是对象锁,synchronizeDemo1和synchronizeDemo2是两个不同的对象所以他们并不能同步
public class SynchronizeDemo {
private int num = 0;
synchronized public void add(){
for (int i = 0; i < 5; i++){
System.out.println(Thread.currentThread().getName() + "----" + (num++));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void add2(){
for (int i = 0; i < 5; i++){
System.out.println(Thread.currentThread().getName() + "----" + (num++));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
test1----0
test2----1
test2----2
test1----2
test1----4
test2----3
test1----5
test2----6
test1----7
test2----8
不是对象锁吗?为什么这里出现不同步了,那是synchronize只能保证他修饰的方法同步,不同线程可以同时访问没有被synchronize修饰的方法。
synchronize代码块的用法和修饰方法差不多
上面的代码等同于
public void add(){
synchronized (this){
for (int i = 0; i < 5; i++){
System.out.println(Thread.currentThread().getName() + "----" + (num++));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
synchronize修饰的代码块同步的就是代码块中的代
synchronized static public void add(){
for (int i = 0; i < 5; i++){
System.out.println(Thread.currentThread().getName() + "----" + (num++));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
当synchronize修饰的是静态方法时他锁住的就是这个类
public static void main(String[] args){
final SynchronizeDemo synchronizeDemo1 = new SynchronizeDemo();
final SynchronizeDemo synchronizeDemo2 = new SynchronizeDemo();
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
synchronizeDemo1.add();
}
},"test1");
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
synchronizeDemo2.add2();
}
},"test2");
thread.start();
thread2.start();
}
你会发现他是同步的,synchronize锁住类之后所以synchronize修饰的方法和方法块将都是同步执行的。这就是synchronize的一些用法