Synchronized
Synchronized的三种应用方法
1.修饰实例方法,作用于当前实例加锁,进入同步代码前要获得当前实例的锁
2.修饰静态方法,作用于当前类对象加锁,进入同步代码前要获得当前类对象的锁
3.修饰代码块,指定枷锁对象,对给定对象加锁,进入同步代码库前要获得给定对象的锁
1.synchronized作用于实例方法
package com.ren; public class AccountingSynchronized implements Runnable{ static int j =0; public synchronized void increase(){ j++; } @Override public void run() { for (int i = 0; i < 1000000; i++) { increase(); } } public static void main(String[] args) throws InterruptedException { AccountingSynchronized accountingSynchronized = new AccountingSynchronized(); Thread t1 = new Thread(accountingSynchronized); Thread t2 = new Thread(accountingSynchronized); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println(j); } }
结果为2000000
2.这是两个线程对共享变量进行操作,new了两个不同的实例对象,存在两个不同的实例对象锁,两者都会进入各自的对象锁,他们两个使用的不是同一把锁,线程安全无法保证
package com.ren; public class AccountingSynchronized implements Runnable{ static int j =0; public synchronized void increase(){ j++; } @Override public void run() { for (int i = 0; i < 1000000; i++) { increase(); } } public static void main(String[] args) throws InterruptedException { Thread thread1 = new Thread(new AccountingSynchronized()); Thread thread2 = new Thread(new AccountingSynchronized()); thread1.start(); thread2.start(); thread1.join(); thread2.join(); System.out.println(j); } }
解决方法:Synchronized作用于静态方法
其锁的对象是当前类的class对象
当将
public synchronized void increase(){j++;}
变为
public static synchronized void increase(){j++;}
结果又变成2000000
3.Synchronized同步代码块
代码块
static AccountingSynchronized instance = new AccountingSynchronized();
synchronized (instance) {}
package com.ren; public class AccountingSynchronized implements Runnable{ static int j =0; static AccountingSynchronized instance = new AccountingSynchronized(); @Override public void run() { synchronized (instance) { for (int i = 0; i < 1000000; i++) { j++; } } } public static void main(String[] args) throws InterruptedException { Thread thread1 = new Thread(instance); Thread thread2 = new Thread(instance); thread1.start(); thread2.start(); thread1.join(); thread2.join(); System.out.println(j); }
synchronized (this) {}//this,当前实例锁
package com.ren; public class AccountingSynchronized implements Runnable{ static int j =0; @Override public void run() { synchronized (this) { for (int i = 0; i < 1000000; i++) { j++; } } } public static void main(String[] args) throws InterruptedException { AccountingSynchronized instance = new AccountingSynchronized(); Thread thread1 = new Thread(instance); Thread thread2 = new Thread(instance); thread1.start(); thread2.start(); thread1.join(); thread2.join(); System.out.println(j); } }
AccountingSynchronized.class//class对象锁
package com.ren; public class AccountingSynchronized implements Runnable{ static int j =0; @Override public void run() { synchronized (AccountingSynchronized.class) { for (int i = 0; i < 1000000; i++) { j++; } } } public static void main(String[] args) throws InterruptedException { AccountingSynchronized instance = new AccountingSynchronized(); Thread thread1 = new Thread(instance); Thread thread2 = new Thread(instance); thread1.start(); thread2.start(); thread1.join(); thread2.join(); System.out.println(j); } }