多线程静态同步函数和非静态同步函数的区别是啥?
静态同步函数:就是方法使用了static关键字修饰
非静态同步函数:没有用static关键字修饰的方法,也就是使用this锁的同步函数
那么静态同步函数使用的啥锁呢?
分析:两个线程,一个线程使用静态同步函数,一个使用同步代码块this锁,如果线程不同步(线程不安全),就说明静态同步函数使用的不是this锁,如果线程同步,就说明使用的是this锁。
好了,我们用代码来进行验证吧:
package com.newDemo.controller.test;
class trainDemo12 implements Runnable{
private static int counttrain=100;//全局变量100
private static Object oj = new Object(); //对象锁
public boolean flag = true; //改变true和false,来改变阀门,
public void run() {
if(flag){
//使用同步代码块
while(counttrain>0){
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (this) { //这段代码只能只能有一个线程进行访问,另一个必须拿到锁的时候才能访问
if(counttrain>0){
System.out.println(Thread.currentThread().getName() + ",出售第" + (100 - counttrain + 1) + "票");
counttrain--;
}
}
}
}else{
//使用同步函数
while(counttrain>0){
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
sale();//出售火车票
}
}
}
//给方法加 static synchronized ,就是静态同步函数,也可以解决线程同步(线程安全问题)
public static synchronized void sale() {
if (counttrain > 0) {
System.out.println(Thread.currentThread().getName() + ",出售第" + (100 - counttrain + 1) + "票");
counttrain--;
}
}
}
public class threadDemo11 {
public static void main(String[] args) throws InterruptedException {
trainDemo12 t0 =new trainDemo12();
Thread t1 = new Thread(t0,"1号窗口");
Thread t2 = new Thread(t0,"2号窗口");
t1.start();
Thread.sleep(50);
t0.flag=false;//改变true和false,来改变阀门,
t2.start();
}
}
结果如下:
结果是线程不安全,就是不同步,所以说明了静态同步函数使用的不是this锁。
那么到底是啥锁呢,其实就是当前字节码文件。对象.class锁
我们可以做个验证,把一个线程使用静态同步函数,一个使用同步代码块字节码文件锁,如果线程不同步(线程不安全),就说明静态同步函数使用的不是this锁,如果线程同步,就说明使用的是字节码文件锁。
代码如下:
package com.newDemo.controller.test;
class trainDemo13 implements Runnable{
/**
* 当一个变量被static修饰时,就会放到jvm的方法区,当class文件被加载的时候就会初始化
*/
private static int counttrain=100;//全局变量100
private static Object oj = new Object(); //对象锁
public boolean flag = true; //改变true和false,来改变阀门,
public void run() {
if(flag){
//使用同步代码块
while(counttrain>0){
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (trainDemo13.class) { //这段代码只能只能有一个线程进行访问,另一个必须拿到锁的时候才能访问
if(counttrain>0){
System.out.println(Thread.currentThread().getName() + ",出售第" + (100 - counttrain + 1) + "票");
counttrain--;
}
}
}
}else{
//使用同步函数
while(counttrain>0){
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
sale();//出售火车票
}
}
}
//给方法加 static synchronized ,就是静态同步函数,也可以解决线程同步(线程安全问题)
public static synchronized void sale() {
if (counttrain > 0) {
System.out.println(Thread.currentThread().getName() + ",出售第" + (100 - counttrain + 1) + "票");
counttrain--;
}
}
}
public class threadDemo12 {
public static void main(String[] args) throws InterruptedException {
trainDemo13 t0 =new trainDemo13();
Thread t1 = new Thread(t0,"1号窗口");
Thread t2 = new Thread(t0,"2号窗口");
t1.start();
Thread.sleep(50);
t0.flag=false;//改变true和false,来改变阀门,
t2.start();
}
}
使用了trainDemo13.class这个锁之后,效果如下:
说明是线程同步的,那就是静态同步函数使用的就是字节码文件。
重点
共享全局变量是静态或者非静态和(同步函数,静态同步函数)么有任何关系。记住了