java的static其实和线程的安全性一点关系都没有,static定义的就是用在类成员变量,在jvm里面就是共享的,一个不恰当的比喻是 像没关门的房子,谁来都能进。但是如果用到synchonrized就可以保证这个房子关上门,只有有钥匙的主人才能进去,所以static和synchonrized是不同的东西,如果强行使用static反而可能导致线程不安全。如果想保证线程安全又想使用static,最好加上synchonrized。
那么static有什么用,正如前面说的没关上门的房子,staitc定义一些无关线程安全的东西,如配置类,工具类这些东西,因为static在jvm里面是独一份的,避免这些方法反而创建而消耗内存,直接调用反而省事。最后贴上代码
package day02;
public class ClassLock {
public static void main(String[] args) throws InterruptedException {
LockDemo01 lockDemo01=new LockDemo01();
LockDemo01 lockDemo02=new LockDemo01();
new Thread(()->{
try {
lockDemo01.staicMethod();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
new Thread(()->{
try {
lockDemo02.staicMethod();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
new Thread(()->{
try {
lockDemo02.staicMethod();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
System.out.println("----获取值----------");
new Thread(()->{
lockDemo01.addNumMthod02();
}).start();
new Thread(()->{
System.out.println(LockDemo01.getNum101());
}).start();
}
}
class LockDemo01<staic> {
static int num=100;
//synchronized 锁住整个类,多个类实例都会被锁住
public synchronized static void staicMethod() throws InterruptedException {
System.out.println(Thread.currentThread().getName()+"进入休眠");
Thread.sleep(100);
System.out.println(Thread.currentThread().getName()+"停止休眠,释放锁");}
//单纯的静态方法无法锁住类
public static int getNum() throws InterruptedException {
Thread.sleep(100);
System.out.println(Thread.currentThread().getName()+"获取值");
Thread.sleep(100);
num+=1;
System.out.println(Thread.currentThread().getName()+"返回值"+num);
return num;
}
/***synchronized锁住对象的实例,只能保证在变量在一个对象里的安全性
* */
public synchronized int addNumMthod() throws InterruptedException {
Thread.sleep(100);
System.out.println(Thread.currentThread().getName()+"获取值");
Thread.sleep(100);
num+=1;
System.out.println(Thread.currentThread().getName()+"返回值"+num);
return num;
}
/** static 存在安全问题
* */
public static int addNumMthod02(){
try {
Thread.sleep(100);
System.out.println(Thread.currentThread().getName()+"获取值");
num+=1;
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"返回值"+num);
return num;
}
static final int getNum101(){
num=num+1;
return num;
}
}
class lockDemo02{
}