多线程的同步问题指的是多个线程同时修改一个数据的时候,可能导致的问题
多线程的问题,又叫Concurrency 问题
在之前的博客中提到过 各个线程会进行竞争CPU资源来执行代码 因此在改数据的时候 如果争相抢占CPU资源来做修改 最后的数据会变成脏数据
比如 线程甲和乙
甲拿到源数据 进行修改 还没来得及修改完 乙就开始拿源数据进行修改 使得最后的数据是乙的操作结果为准的 但是往往预期功能实现的不是这样
得到数据也就被称为脏数据。这种情况往往是建立在多次运行之后产生的
解决方法:
为此引入 占用释放 来有序的对数据进行操作 也就是某线程占用后其他线程无权进行数据修改 只能等待释放之后进行占用操作。
实现这一功能需要关键字——synchronized() 和this super一样
this的作用要清楚 是指当前对象——也就是执行一系列关于含有this的操作的这个引用
具体运用synchronized关键字的几种表示方法:
1、在以匿名类的形式写线程类的时候 在run方法里可以添加synchronized
传入参数 可以是自定义的引用对象 也可以是
final Object someobject=new Object();
synchronized表示当前线程,独占 对象 someobject
为什么称之为 同步对象 为的是突出占用了此对象后其他线程无法占用
即把同步对象作为参数传入执行synchronized块中的语句
2、在设计的类里的方法添加synchronized修饰符进行修饰
public synchronized void supplies()
{
patience++;
}
或者在方法中嵌套一个synchronized块
public void cutdown()
{
synchronized (this) {
patience--;
}
}
在 测试类中实例化该设计类的对象时 外部访问调用该方法时就默认是占有了该对象不用再如方法一写一个synchronized块
介绍线程安全的类:
一个类,其方法都是有synchronized修饰的,那么该类就叫做线程安全的类
同一时间,只有一个线程能够进入, 这种类的一个实例 去修改数据,进而保证了这个实例中的数据的安全(不会同时被多线程修改而变成脏数据)
如StringBuffer就是 而StringBulider不是
个人理解:
synchronized 的运用就像是标识 —— 安全标识 在码代码实现功能时添加synchronized关键字会使得数据不会被多线程同时修改而变成脏数据。