总览
- 多线程+对象在方法内部
- 多线程+对象在方法外部
- 多线程+单对象+synchronized
- 多线程+多对象+synchronized
- 多线程+synchronized+static
- 多线程+单对象+synchronized+static
- 多线程+多对象+synchronized+static
多线程+单对象+synchronized(例子)
(1)HasSelPrivateNum.java类
public class HasSelPrivateNum {
private int num = 0;
//注意添加了synchronized关键字
synchronized public void addI(String username) {
try {
if (username.equals("a")) {
num = 100;
System.out.println("a set over");
Thread.sleep(2000);
} else {
num = 200;
System.out.println("b set over");
}
System.out.println(username + " num=" + num);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
(2)ThreadA.java
public class ThreadA extends Thread {
private HasSelPrivateNum numRef;
public ThreadA(HasSelPrivateNum numRef) {
super();
this.numRef = numRef;
}
@Override
public void run() {
super.run();
numRef.addI("a");
}
}
(3)ThreadB.java
public class ThreadB extends Thread {
private HasSelPrivateNum numRef;
public ThreadB(HasSelPrivateNum numRef) {
super();
this.numRef = numRef;
}
@Override
public void run() {
super.run();
numRef.addI("b");
}
}
(4)Run.java
public class Run {
public static void main(String[] args) {
HasSelPrivateNum numRef = new HasSelPrivateNum();
ThreadA a = new ThreadA(numRef);
a.start();
ThreadB b = new ThreadB(numRef);
b.start();
}
}
运行结果
原理图(对象锁)
总结
-
上面的例子添加了
synchronized
关键字,可以看到现在是线程安全的了。 -
注意关键字
synchronized
关键字获得的锁都是对象锁,而不是把addI()
方法上锁,比如上面这个例子是ThreadA
先执行了addI()
方法,所以ThreadA
就持有numRef
这个对象的锁,此时ThreadA
还没执行完时,ThreadB
只能一直等待,因为THreadB
也要使用numRef
对象,而numRef
对象被ThreadA
锁住了。 -
这里演示的是
ThreadA
和ThreadB
都去争抢一个相同的对象,那么要是有2个对象呢?就会造成多个对象多个锁的情况,也就是多线程+多对象+synchronized。