线程安全的概念:当多个线程访问某个类(对象或者方法)的时候,这个类始终表现出正确的行为,那么这个类(对象或者方法)就是线程安全的。
synchronized:可以在任意的对象以及方法上加锁,实现线程互斥。而加锁的这块代码叫做互斥区或者叫做临界区。
当多个线程访问线程的run()方法的时候,以排队的方式进行处理(也就是按照CPU分配的先后顺序而定的,并非咱们所写的代码顺序决定的)。多个线程去尝试拿到锁,只有拿到锁的线程才能只能临界区的代码,其余没有拿到锁的线程们就要等待。
多个线程多个锁:多个线程,每个线程都可以拿到自己的锁,分别拿到锁之后分别执行临界区的代码。若是没有处理好就会出现异常,无法实现线程内数据共享,解决方法就是在同步方法上面加上static修饰,使得原先的对象锁变成类锁。
示例:我现在需要判断进来的一个值如果是a,就将变量num设置成100,并且打印出num的值,此外就将num的值设置成200打印出来。
package com.tgb.thread;
/**
* Created by lenovo on 2017/8/9.
*/
public class ClassLock {
private /*static*/ int num=0;
public /*static*/ synchronized void printNum(String tag) {
try {
if (tag.equals("a")) {
num = 100;
System.out.println(Thread.currentThread().getName()+":tag a set over");
Thread.sleep(1000);
}else{
num=200;
System.out.println(Thread.currentThread().getName()+":tab b set over");
}
}catch (Exception e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+":tag "+tag+" num:"+num);
}
public static void main(String[] args) {
final ClassLock one=new ClassLock();
final ClassLock two=new ClassLock();
new Thread(new Runnable() {
public void run() {
one.printNum("a");
}
}).start();
new Thread(new Runnable() {
public void run() {
two.printNum("b");
}
}).start();
}
}
看最后的效果:
然后将方法上面的static关键字的代码注释取消掉,效果如下: