当前位置: 首页 > news >正文

批量发布文章到wordpress百度seo效果

批量发布文章到wordpress,百度seo效果,想做一个赌钱网站怎么做,美国邮政网站引言: 如果多线程环境下代码运行的结果是符合我们预期的,即在单线程环境应该的结果,则说这个程序是线程安全的 线程安全问题的原因: 一.操作系统的随机调度 : 二.多个线程修改同一个变量: 三.修改操作不是…

引言: 

如果多线程环境下代码运行的结果是符合我们预期的,即在单线程环境应该的结果,则说这个程序是线程安全的


线程安全问题的原因:

一.操作系统的随机调度 :

二.多个线程修改同一个变量: 

三.修改操作不是原子的 :

四.内存可见性 :

五.指令重排序:  

解决上述的线程安全问题的措施:   



线程安全问题的原因:

 一.操作系统的随机调度 :  

1. 这是线程安全问题的 罪魁祸首 随机调度使⼀个程序在多线程环境下, 执行顺序存在很多的变数.

例子:这个代码返回结果就是随机调度的体现 

 现象: 

class MyThread extends Thread {@Overridepublic void run() {while (true) {System.out.println("这⾥是t线程运⾏的代码");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}
}public class Demo1 {public static void main(String[] args) throws InterruptedException {MyThread t = new MyThread();t.start();while (true) {System.out.println("这里是主线程");Thread.sleep(1000);}}
}

现象: 


二.多个线程修改同一个变量: 

上⾯的线程不安全的代码中, 涉及到多个线程针对 count 变量进行修改.
此时这个 count 是⼀个多个线程都能访问到的 "共享数据" 
 

例子:下面这个代码应该预期应该自增10w次,但是由于线程安全问题,达不到预期 
public class Demo11 {private static int count = 0;public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(() -> {for (int i = 0; i < 50000; i++) {count++;}System.out.println("t1 结束");});Thread t2 = new Thread(() -> {for (int i = 0; i < 50000; i++) {count++;}System.out.println("t2 结束");});t1.start();t2.start();t1.join();t2.join();// 一个线程自增 5w 次, 两个线程, 总共自增 10w 次. 预期结果, count = 10wSystem.out.println(count);}
}

三.修改操作不是原子的 : 

这里我们count++,时候站在操作系统层面,我们要进行大致三步:

load:把count的值读到寄存器里 

add: 把寄存器中的内容加1

save:  把寄存器写回内存  

进行以上以上操作时候由于操作系统随机调度多个线程之间,可能出现数据被覆盖的情况,这就是操作不原子的体现: 


四.内存可见性 : 

这个问题可以引入Java内存模型说明: 

线程之间的共享变量存在 主内存 (Main Memory).(主内存就是泛指的内存)
每⼀个线程都有自己的 "工作内存" (Working Memory) .(工作内存指的是CPU 的寄存器和高速缓存L1,L2,L3)
当线程要读取一个共享变量的时候, 会先把变量从主内存拷贝到工作内存(CPU 的寄存器), 再从工作内存(CPU 的寄存器),读取数据。 
其实是通过jvm和编译器来实现优化,把读内存优化为读寄存器了,有时候这个优化逻辑不符合我们的预期的逻辑出现细节上的偏差,就导致内存可见性问题

代码实例:一个线程读取一个线程修改
这个循环条件的flag判断是条件跳转指令cmp是寄存器操作会很快,while会循环很多次,jvm觉得每次觉得读到的都是0,直接就把 读内存优化为读寄存器了, 此时寄存器的值为0,此时用户输入 1 想结束线程时,t1线程读不到这个在内存中(主内存)的值,所以这个t1线程结束不了
public static void main(String[] args) {Thread t1 = new Thread(()->{while (flag == 0){}System.out.println("t1线程结束");});Thread t2 = new Thread(()->{Scanner in = new Scanner(System.in);System.out.println("请输入flag的值");flag = in.nextInt();});t1.start();t2.start();}


五.指令重排序:

要说清楚这个问题就要引入一种设计模式:单例模式

 单例模式: 

单例模式能保证某个类在程序中只存在唯⼀⼀份实例, 而不会创建出多个实例,不能创建多个对象,这里有两种写法:饿汉模式和懒汉模式: 

1.饿汉模式:  类加载的同时, 创建实例:  
类加载时就new对象所以成为饿汉模式,注意构造方法私有化,防止类外多次实例化。
​
class Singleton {private static Singleton instance = new Singleton();//类加载时就new对象//构造方法私有化,防止类外被实例化多个对象private Singleton() {}public static Singleton getInstance() {return instance;}
}​

2.懒汉模式-单线程版:  

懒汉模式,能不实例化就不实例化所以的懒汉, 第⼀次使用的时候才创建实例

class Singleton {private static Singleton instance = null;private Singleton() {}public static Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}
}

 但是这个在多线程下还是存在线程安全问题的,而且还有一个指令重排序问题 。

 就算加锁(结合下面看看),解决了线程安全问题,但是instance = new Singleton();

new对象操作,细分为这三步:

1 .申请内存空间

2.构造对象(初始化)

3.内存空间首地址,赋值给引用变量  
由于指令重排序,可能会改变顺序,顺序可能从1,2,3一一>1,3,2  
在这个代码情况下就可能,在类外调用,getInstance方法拿到未初始化的对象导致线程安全问题。
 
class Singleton {private static Singleton instance = null;private static Object locker = new Object(); private Singleton() {}public synchronized static Singleton getInstance() {if(instance == null) {//进一步优化效率,减少锁的阻塞状态,(instance == null才加锁才new对象)synchronized(locker){if (instance == null) {instance = new Singleton();}}}return instance;}}



解决上述的线程安全问题的措施:   

操作系统的随机调度 是操作系统,计算机一脉传承,不能解决,
接下来我们围绕三~四~五~展开 

三.修改操作不是原子的 : 

这里我们可以把相关的操作打包起来,就是引入锁:

synchronized 关键字 - 监视器锁 monitor lock :

synchronized 会起到互斥效果, 某个线程执⾏到某个对象的 synchronized 中时, 其他线程如果也执行 到同⼀个对象 synchronized 就会阻塞等待.
进⼊ synchronized 修饰的代码块, 相当于 加锁
退出 synchronized 修饰的代码块, 相当于 解锁 
 就和上厕所一样:

理解 "阻塞等待":
针对每⼀把锁, 操作系统内部都维护了⼀个等待队列. 当这个锁被某个线程占有的时候, 其他线程尝试 进行加锁, 就加不上了, 就会阻塞等待, ⼀直等到之前的线程解锁之后, 由操作系统唤醒⼀个新的线程, 再来获取到这个锁。
注意:这里还有一种应用程序级别的忙等,不涉及操作系统

三.的解决代码:

这里注意两个线程要加他一把锁,才有互斥的效果。 

 

 private static int count = 0;public static void main(String[] args) throws InterruptedException {Object locker = new Object();Thread t1 = new Thread(() -> {synchronized (locker) {for (int i = 0; i < 50000; i++) {count++;}}System.out.println("t1 结束");});Thread t2 = new Thread(() -> {synchronized (locker) {for (int i = 0; i < 50000; i++) {count++;}}System.out.println("t2 结束");});t1.start();t2.start();t1.join();t2.join();// 一个线程自增 5w 次, 两个线程, 总共自增 10w 次. 预期结果, count = 10wSystem.out.println(count);}
  

四.内存可见性解决:  

这里引入volatile关键字:


1.volatile 能保证每次读取操作都是读内存

2.volatile 能保证变量的读取和修改不会出发指令重排序 

​public class{
public volitile static int flag = 0 //这样修饰变量编译器就不会优化了
public static void main(String[] args) {Thread t1 = new Thread(()->{while (flag == 0){}System.out.println("t1线程结束");});Thread t2 = new Thread(()->{Scanner in = new Scanner(System.in);System.out.println("请输入flag的值");flag = in.nextInt();});t1.start();t2.start();}​}

五.指令重排序:

饿汉模式是没有线程安全问题和指令重排序的,因为都是读操作

懒汉模式下就会有:

我们也加上volatile关键字:

​
class Singleton {private static volatile Singleton instance = null;//加上volatile private static Object locker = new Object(); private Singleton() {}public synchronized static Singleton getInstance() {if(instance == null) {//进一步优化效率,减少锁的阻塞状态,(instance == null才加锁才new对象)synchronized(locker){if (instance == null) {instance = new Singleton();}}}return instance;}}​

http://www.fp688.cn/news/159173.html

相关文章:

  • 企业展厅效果图大全博客优化网站seo怎么写
  • 怎么在网上卖东西?温州seo优化公司
  • 欧美做的爱爱网站有哪些网络优化培训骗局
  • 外贸公司怎么接订单网站怎样优化seo
  • 网站空间和服务器的区别适合发朋友圈的营销广告
  • 东丽区网站建设公司必应bing搜索引擎
  • 做电子商务网站公司建官网要多少钱
  • 做网站是先做界面还是先做后台网站引流推广
  • 无锡哪家做网站好sem竞价培训
  • wordpress做出影视网站seo教程网
  • 笨鸟网站开发电话百度
  • 专业做网站app的公司百度提升排名
  • 宁波网站设计一手app推广接单平台
  • 外贸商城网站制作公司深圳网站设计公司排行
  • 代做网站推广的公司关键词推广软件排名
  • 唐山seo网络推广手机网络优化
  • 有人找做网站的大数据下的精准营销
  • sap软件金昌网站seo
  • 俄语网站建设360搜索引擎的特点
  • seo专业技术培训谷歌广告优化
  • 网站兼容代码绍兴seo排名收费
  • 网站建设服务器常用的网络营销推广方法有哪些
  • 临安做网站艺考培训学校
  • p2p商城网站建设什么是软文营销
  • 无锡网站建设解决方案企业seo顾问
  • 鸡泽网站建设开发做一个网站需要多少钱
  • 自助下单网站千峰培训
  • 杭州自助建站模板关键词优化是什么意思?
  • 用顶级域名做网站好吗管理微信软件
  • 大英哪里有做网站的济南做seo外包