Java多线程专题-synchronized的使用

为什么有线程安全问题?

当多个线程同时共享同一个全局变量或静态变量,做写的操作时,可能会发生数据冲突问题,也就是线程安全问题。但是做读操作是不会发生数据冲突问题。

使用同步方式解决线程安全

问:如何解决多线程之间线程安全问题?

答:使用多线程之间同步synchronized或使用锁(lock)。

问:为什么使用线程同步或使用锁能解决线程安全问题呢?

答:将可能会发生数据冲突问题(线程不安全问题),只能让当前一个线程进行执行。代码执行完成后释放锁,让后才能让其他线程进行执行。这样的话就可以解决线程不安全问题。

问:什么是多线程之间同步?

答:当多个线程共享同一个资源,不会受到其他线程的干扰。

Synchronized同步代码块

synchronized(同一个数据){
    可能会发生线程冲突问题
}

synchronized后面的数据必须为同一对象

同步函数

/**
 * 在方法上修饰synchronized 称为同步函数
 */
public synchronized void sale() {
    if (trainCount > 0) { 
        try {
            Thread.sleep(40);
        } catch (Exception e) {
        }
        System.out.println(Thread.currentThread().getName() + ",出售 第" + (100 - trainCount + 1) + "张票.");
        trainCount--;
    }
}

此时,同一个对象的该方法只能被一个线程执行,其他线程等待该线程执行完毕才能获得执行权限。

同步函数使用this锁。一个线程使用同步代码块(this明锁),另一个线程使用同步函数。如果两个线程抢票不能实现同步,那么会出现数据错误。

静态同步函数

  • 方法上加上static关键字,使用synchronized 关键字修饰 或者使用类.class文件。
  • 静态的同步函数使用的锁是  该函数所属字节码文件对象
  • 可以用 getClass方法获取,也可以用当前  类名.class 表示。

代码样例:

synchronized (ThreadTrain.class) {
    System.out.println(Thread.currentThread().getName() + ",出售 第" + (100 - trainCount + 1) + "张票.");
    trainCount--;
    try {
        Thread.sleep(100);
    } catch (Exception e) {
    }
}

总结

synchronized 修饰方法使用锁是当前this锁。

synchronized 修饰静态方法使用锁是当前类的字节码文件

 

 

 

 

©️2020 CSDN 皮肤主题: 书香水墨 设计师:CSDN官方博客 返回首页