关键字synchronized是比较常见的多线程方法,对于多线程操作某一个方法时,需要对加上synchronized来进行方法内对变量的一致性。
请看下面的代码:
package Thread;
/**
* Created by zhangzheming on 2018/1/10.
*/
public class MultiThread {
private int num = 0;
public synchronized void printNum(String tag){
try{
if ("a".equals(tag)){
num = 100;
System.out.println("tag a set num end!");
Thread.sleep(1000);
}else {
num = 200;
System.out.println("tag b set num over!");
}
System.out.println("tag "+tag+",num= "+num);
}catch (Exception e){
e.printStackTrace();
}
}
public static void main(String[] args){
final MultiThread m1 = new MultiThread();
final MultiThread m2 = new MultiThread();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
m1.printNum("a");
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
m2.printNum("b");
}
});
t1.start();
t2.start();
}
}
运行结果
不知道大家是否看出有什么问题了?
是不是两个线程没有按照先后顺序进行操作,是的,那问题在哪儿呢?
其实问题很简单,那就是m1和m2是两个线程对象,对于锁的概念是每个对象都有一把锁,也就是对于synchronized 是对象锁,而不是把一段代码当做锁,另外,两个对象,线程获取的是两个不同的锁,他们互不影响。
那怎么解决这个多线程问题呢?
其实很简单,那就是在synchronized 前使用static声明,表示锁定class类,类级别锁(独占锁)。
package Thread;
/**
* Created by zhangzheming on 2018/1/10.
*/
public class MultiThread {
private static int num = 0;
public static synchronized void printNum(String tag){
try{
if ("a".equals(tag)){
num = 100;
System.out.println("tag a set num end!");
Thread.sleep(1000);
}else {
num = 200;
System.out.println("tag b set num over!");
}
System.out.println("tag "+tag+",num= "+num);
}catch (Exception e){
e.printStackTrace();
}
}
public static void main(String[] args){
final MultiThread m1 = new MultiThread();
final MultiThread m2 = new MultiThread();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
m1.printNum("a");
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
m2.printNum("b");
}
});
t1.start();
t2.start();
}
}
运行结果
现在所有的结果就运行正确了!
下面这篇文章讲得比较详细关于synchronized
http://www.importnew.com/20444.html
网友评论