多线程同步使用sychronized,要注意加锁的对象要正确。
package com.oy.example.multithread.sychronization.lockobject;
/**
* 对于不同的临界资源,需要加不同的锁
* @author Administrator
*
*/
public class Main {
public static void main(String[] args) throws InterruptedException {
AddAThread addAThread = new AddAThread();
DecAThread decAThread = new DecAThread();
AddBThread addBThread = new AddBThread();
DecBThread decBThread = new DecBThread();
addAThread.start();
decAThread.start();
addBThread.start();
decBThread.start();
addAThread.join();
decAThread.join();
addBThread.join();
decBThread.join();
System.out.println(Counter.numA);
System.out.println(Counter.numB);
}
}
class Counter {
public static final Object lockA = new Object();
public static final Object lockB = new Object();
public static int numA = 0;
public static int numB = 0;
}
class AddAThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 20000; i++) {
synchronized (Counter.lockA) {
Counter.numA = Counter.numA + 1;
}
}
}
}
class DecAThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 20000; i++) {
synchronized (Counter.lockA) {
Counter.numA = Counter.numA - 1;
}
}
}
}
class AddBThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 20000; i++) {
synchronized (Counter.lockB) {
Counter.numB = Counter.numB + 1;
}
}
}
}
class DecBThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 20000; i++) {
synchronized (Counter.lockB) {
Counter.numB = Counter.numB - 1;
}
}
}
}
通过线程加锁,可能会由于逻辑复杂选择错了加锁的对象,所以更好的方法是把synchronized的逻辑封装起来。
package com.oy.example.multithread.sychronization.lockmethod;
public class Main {
public static void main(String[] args) throws InterruptedException {
Counter c = new Counter();
AddAThread addAThread = new AddAThread(c);
DecAThread decAThread = new DecAThread(c);
addAThread.start();
decAThread.start();
addAThread.join();
decAThread.join();
System.out.println(c.getA());
}
}
class Counter {
public int numA = 0;
public void addA() {
synchronized(this) {//锁住Counter对象实例
numA++;
}//解锁
}
public void decA() {
synchronized(this) {//锁住Counter对象实例
numA--;
}//解锁
}
public int getA() {
return numA;
}
}
class AddAThread extends Thread {
private Counter c;
public AddAThread(Counter c) {
this.c = c;
}
@Override
public void run() {
for (int i = 0; i < 20000; i++) {
c.addA();
}
}
}
class DecAThread extends Thread {
private Counter c;
public DecAThread(Counter c) {
this.c = c;
}
@Override
public void run() {
for (int i = 0; i < 20000; i++) {
c.decA();
}
}
}
也可以用synchronized修饰方法,此时表示调用方法之前锁住对象实例。调用this实例synchronized修饰的方法时,this实例其他synchronized修饰的方法需要等待this实例的锁释放才能调用。
public void addA() {
synchronized(this) {//锁住Counter对象实例
numA++;
}//解锁
}
可以改为
public synchronized void addA() {//锁住Counter对象实例
numA++;
}//解锁
对于一个静态方法如果使用synchronized修饰,表示锁住的是Class实例。