java 多进程读锁_java-多线程与锁 - osc_ug2wy0bi的个人空间 - OSCHINA - 中文开源技术交流社区...

概述:

多线程的使用,锁,线程池,更多的锁。

1:多线程的使用。

1.1:使用多线程需要保证:原子性,可见性,有序性。

1.2:启动多线程的方法:(不做 多余赘述,写两种常见的方式)

继承Thread类,重写run方法。

实现Runnable接口,重写run方法。

1.3:这里引出一个方法  join()。(一个执行先后的方法)

假设开启了两个线程T1,T2,如果同时 start 之后T1,T2的执行顺序比较随机,如果在T2的 run 方法中写上T1.join(),那么就是说T2在T1执行完之后执行。

2:高并发保证线程安全:锁。

2.1:分类:synchronized(内置锁),lock。

2.2:区别:lock需要unlock方法手动解锁,synchronized在执行完锁的部分或者异常就是释放锁。

2.3:对于synchronized的使用。(解决的是高并发情况多线程公用一个变量引起的线程安全问题)

2.3.1:同步方法。

public classTest {/*** 同步方法

* 说明:锁的对象:这个类,即Test类,也叫this锁。*/

public synchronized voidsyncTest() {//TODO Auto-generated method stub

}

}

2.3.2:同步代码块。

public classTest {private Object object = newObject();/*** 同步代码块

* 说明:锁的对象:

* 这个类,即Test类,

* 也可以的一对象。

* 以下两种皆可*/

public voidsyncTest() {//锁的类

synchronized (this) {

}//锁的对象

synchronized(object) {

}

}

}

2.3.3:静态同步代码。

public classTest {/*** 同步代码块

* 说明:锁的对象:

* 这个类(即Test类)的字节码文件,*/

public static voidsyncTest() {synchronized (Test.class) {

}

}

}

2.4:延伸的概念。

2.4.1:修饰词 threadLocal(解决的是多线程之间公用的变量隔离出来使用,不影响其他线程)

概述:将共享变量私有化。具体使用网上有很多的帖子。

2.4.2:修饰词 volatile (修改变量,快速写入主内存)

解释说明:首先了解共享内存模型(jmm),即一个变量在内存中存于主内存,还有一块虚拟的私有内存(虚拟的,不存在的)。

内存结构是我们常说的 jvm。

普通变量:修改的是自己私有内存的变量,然后再同步到主内存中。

被volatile 修饰的变量:1:会快速的被写入主内存,然后其他线程使用时候直接从主内存中拿取。我的理解是不是volatile 修饰的变量

一直操作的是主内存中的呢?(没有看过源码进行深入的研究,只是一个疑问,不过不太影响对这个的理解)

2:volatile 可以禁止指令重排序(指令重排是cpu为了提高程序的执行性能的一种方法)。

对比synchronized:

1:优点,volatile 不会造成线程阻塞,性能方面要由于锁。volatile 可以禁止指令重排序。

2:缺点,volatile 是可以保证可见性,有序性,但是不能保证原子性,所以不能取代synchronized。

总结:volatile 是轻量级的synchronized,如果有对变量进行操作等场景使用synchronized。

使用场景:

单例模式是个典型的应用。

说明:变量需要volition修饰,变量的构造赋值部分是用synchronized修饰的,目的是T1进入了synchronized部分之后,

如果对象还未完全构建成功,那么T2进入,发现判断的对象不为null,这样会存在问题。

2.4.3:wait(),notify(),notifyAll()应用。(wait让线程进入等待状态,notify唤醒当前线程,notifyAll唤醒所以线程)

假设场景 :假如对一个共享变量,T1进行set值,T2进行get值。我们要保证:T2 get值时候,变量里面要有值的,T1 set值时候变量是无指的。

T1与T2中使用wait(),notify()组合。

对比 sleep() :sleep等待多长时间继续执行,不会释放锁。wait会释放锁。

3:线程池。

3.1:为何使用线程池:

频繁的以1的描述方式开启线程,关闭线程,很消耗性能,所以引入线程池。

3.2:线程池种类:

newCachedThreadPool:缓存线程池

newFixedThreadPool:定长线程池

3.3:spring项目中的应用。(自定义一个线程池)

@Configuration

@EnableAsync//开启异步调用

public classTest {/*** 详细的参数解释可参见,里面有相应的线程池参数配置规则

*https://www.cnblogs.com/waytobestcoder/p/5323130.html*@return

*/@Bean("pool1")publicExecutor threadPool1() {

ThreadPoolTaskExecutor threadPoolTaskExecutor= newThreadPoolTaskExecutor();//线程核心数目

threadPoolTaskExecutor.setCorePoolSize(10);//核心线程,超时是否关闭,一般缓存线程池默认60S,其他线程池设置的是0S,我们默认这个也是60S

threadPoolTaskExecutor.setAllowCoreThreadTimeOut(true);//最大线程数

threadPoolTaskExecutor.setMaxPoolSize(10);//配置队列大小

threadPoolTaskExecutor.setQueueCapacity(50);//配置线程池前缀,相当于@Bean("pool1")已经指定了使用的线程池名称//threadPoolTaskExecutor.setThreadNamePrefix("pool1");//配置拒绝策略

threadPoolTaskExecutor.setRejectedExecutionHandler(newThreadPoolExecutor.AbortPolicy());//数据初始化

threadPoolTaskExecutor.initialize();returnthreadPoolTaskExecutor;

}

}

@Async("pool1")public voidtest(){

}

如果调用了test(),就是使用了线程池pool1。

4:更多的锁

4.1:乐观锁,悲观锁,重入锁,自旋锁,分布式锁,CAS无锁

CAS概述:三个值,初始值,期望值,新值。如果初始值=期望值,那么初始值=新值,否则代表有其他线程已经改了,再重新取值对比。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值