多线程中的线程安全问题
概述:
多条线程在操作同一个资源的时候发生的数据交叉问题就是线程安全问题
产生原因:
多条线程操作同一个资源
解决思路:
要线程排队解决安全问题,设定权限。
如何设定权限?
在容易发生线程安全的代码段上加权限,得到权限就可以执行并且执行完,把权限还给jvm。
权限:
java中权限称之为锁,其实就是一个引用数据类型对象,不同的权限的设置方式有不同的
锁
注意:权限【锁】必须要唯一
解决方式:
同步代码块
同步方法
Lock锁
一、同步代码块
概述:
属于代码块的一种格式,主要目的就是用于解决多线程的线程安全问题,可以给代码段加锁对象,使用关键字synchronized 实现
语法格式:
synchronized ( 锁对象 ) {
发生线程安全问题的代码
}
锁对象:
任何引用数据类型的对象都可以作为同步代码块的对象 【任意的引用数据类型的对象】
注意:
没有确定锁对象的时候,可以是任意的引用数据类型的对象
一旦确定了锁对象,全程都要保证锁对象的唯一性。
代码示例:
public class SynchronizedDemo implements Runnable{
//创建锁对象,要保证锁对象的唯一性
final static SynchronizedDemo sd = new SynchronizedDemo();
@Override
public void run() {
//创建循环,打印100遍循环体中内容
for (int i = 0; i < 100; i++) {
//创建同步代码块,解决线程安全问题
// synchronized ("a") //任何引用数据类型的对象都可以作为同步代码块的对象
synchronized (sd) {
System.out.print("i ");
System.out.print("LOVE ");
System.out.println("JAVA");
}
}
}
}
测试类:
public class TestSynchronizedDemo {
public static void main(String[] args) {
//创建任务对象
SynchronizedDemo sd = new SynchronizedDemo();
//创建线程对象,并绑定任务对象
Thread t1 = new Thread(sd);
Thread t2 = new Thread(sd);
//开启线程
t1.start();
t2.start();
}
}
二、同步方法
概述:
被关键字synchronized修饰的方法就是同步方法,包括普通方法和静态方法两种
语法格式:
修饰符 【static】 synchronized 返回值类型 方法名 (参数列表){方法体}