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

wordpress怎么自动更新网站地图友情链接交换方式有哪些

wordpress怎么自动更新网站地图,友情链接交换方式有哪些,平板网站建设,wordpress发文章设置文字大小本节⽬标 • 认识多线程 • 掌握多线程程序的编写 • 掌握多线程的状态 • 掌握什么是线程不安全及解决思路 • 掌握 synchronized、volatile 关键字 1. 认识线程(Thread) 1.1 概念 1) 线程是什么 ⼀个线程就是⼀个 "执⾏流". 每个线…
本节⽬标
认识多线程
掌握多线程程序的编写
掌握多线程的状态
掌握什么是线程不安全及解决思路
掌握 synchronized、volatile 关键字

1. 认识线程(Thread)

1.1 概念

1) 线程是什么

⼀个线程就是⼀个 "执⾏流". 每个线程之间都可以按照顺序执⾏⾃⼰的代码. 多个线程之间 "同时" 执⾏着多份代码.
2) 为啥要有线程
⾸先, "并发编程" 成为 "刚需".
线程之间的共享变量存在 主内存 (Main Memory).
每⼀个线程都有⾃⼰的 "⼯作内存" (Working Memory) .
当线程要读取⼀个共享变量的时候, 会先把变量从主内存拷⻉到⼯作内存, 再从⼯作内存读取数据.
3) 进程和线程的区别
  1. 进程是包含线程的. 每个进程⾄少有⼀个线程存在,即主线程。
  2.  进程和进程之间不共享内存空间. 同⼀个进程的线程之间共享同⼀个内存空间。
  3. 进程是系统分配资源的最⼩单位,线程是系统调度的最⼩单位。
  4. ⼀个进程挂了⼀般不会影响到其他进程. 但是⼀个线程挂了, 可能把同进程内的其他线程⼀起带⾛(整个进程崩溃).

4) Java 的线程 和 操作系统线程 的关系 

线程是操作系统中的概念. 操作系统内核实现了线程这样的机制, 并且对⽤⼾层提供了⼀些 API 供⽤⼾使⽤(例如 Linux 的 pthread 库).
Java 标准库中 Thread 类可以视为是对操作系统提供的 API 进⾏了进⼀步的抽象和封装.

 1.2 第⼀个多线程程序

感受多线程程序和普通程序的区别:
每个线程都是⼀个独⽴的执⾏流
多个线程之间是 "并发" 执⾏的.

可以使用jconsole观察线程的状态,具体怎么使用后面学习.

 1.3 创建线程

⽅法1 继承 Thread 类
继承 Thread 来创建⼀个线程类,
class MyThread extends Thread {@Overridepublic void run() {System.out.println("这⾥是线程运⾏的代码");}
}
创建 MyThread 类的实例
MyThread t = new MyThread();
调⽤ start ⽅法启动线程
t.start(); // 线程开始运⾏
⽅法2 实现 Runnable 接⼝
1. 实现 Runnable 接⼝
class MyRunnable implements Runnable {@Overridepublic void run() {System.out.println("这⾥是线程运⾏的代码");}
}
2. 创建 Thread 类实例, 调⽤ Thread 的构造⽅法时将 Runnable 对象作为 target 参数.
Thread t = new Thread ( new MyRunnable ());

 方法3:匿名内部类,创建Thread子类

方法4:匿名内部类,创建Runnable子类

 方法5:lambda表达式

2. Thread 类及常⻅⽅法

 2.1 Thread 的常⻅构造⽅法

演示:

Thread t1 = new Thread();
Thread t2 = new Thread(new MyRunnable());
Thread t3 = new Thread("这是我的名字");
Thread t4 = new Thread(new MyRunnable(), "这是我的名字");

 2.1 Thread 的⼏个常⻅属性(重点)

属性获取方法
IDgetId()
名称getName()
状态getState()
优先级getPriority()
是否为后台线程

isDaemon()

是否存活isAlive()
是否被中断isInterrupted()

解释:

ID 是线程的唯⼀标识,不同线程不会重复
名称是各种调试⼯具⽤到
状态表⽰线程当前所处的⼀个情况,下⾯我们会进⼀步说明
优先级⾼的线程理论上来说更容易被调度到(抢占资源)
关于后台线程,需要记住⼀点: JVM会在⼀个进程的所有⾮后台线程结束后,才会结束运⾏。
是否存活,即简单的理解,为 run ⽅法是否运⾏结束了
线程的中断问题,等等我们会解释到。

是否为后台线程:

 

一次都没有打印就结束,因为main线程结束的很快。mian是前台线程,thread是后台线程。也可以判断线程是否为后台线程。

是否存活:

2.2线程的中断(重点)

 ⽬前常⻅的有以下两种⽅式:

1. 通过共享的标记来进⾏沟通
2. 调⽤ interrupt() ⽅法来通知

标志位 中断(终止)

 调用intterrupt()

 解释

 但是这里有一个问题:

会一直陷入死循环,为什么,

解释:

解决方法:

加上break

2.3等待⼀个线程 - join()

比如说:现在有两线程a,b,在a线程中调用b.join()

就是a线程等待b线程先结束,a线程在执行。

join的作用:就是能让先结束的线程先结束

 2.4 获取当前线程引⽤

这个方法我们已经很熟悉了,用来获取当前线程的引用。

 2.5休眠当前线程(sleep)

3. 线程的状态

打印线程状态:线程变量名.getState();

 

这个我就不多演示,后面我会给大家带来jcomsole工具,java自带工具的使用。 

 4. 多线程带来的的⻛险-线程安全 (重点)

4.1 观察线程不安全 

比如说:现在让两个

代码:

public class Demo9 {private static int count = 0;public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(() -> {// 对 count 变量增5w次for (int i = 0; i < 50000; i++) {count++;}});Thread t2 = new Thread(() -> {// 对 count 变量增5w次for (int i = 0; i < 50000; i++) {count++;}});t1.start();t2.start();t1.join();t2.join();// 预期结果应该是 10wSystem.out.println("count: " + count);}
}

结果:

原因:

 

4.2 线程安全的概念 

想给出⼀个线程安全的确切定义是复杂的,但我们可以这样认为:
如果多线程环境下代码运⾏的结果是符合我们预期的,即在单线程环境应该的结果,则说这个程序是线程安全的。

4.3 线程不安全的原因

线程调度是随机的
随机调度使⼀个程序在多线程环境下, 执⾏顺序存在很多的变数.
程序猿必须保证 在任意执⾏顺序下 , 代码都能正常⼯作
原⼦性

什么是原⼦性

我们把⼀段代码想象成⼀个房间,每个线程就是要进⼊这个房间的⼈。如果没有任何机制保证,A进⼊房间之后,还没有出来;B 是不是也可以进⼊房间,打断 A 在房间⾥的隐私。这个就是不具备原⼦性的。
是不是只要给房间加⼀把锁,A 进去就把⻔锁上,其他⼈是不是就进不来了。这样就保证了这段代码的原⼦性了。 有时也把这个现象叫做同步互斥,表⽰操作是互相排斥的。
⼀条 java 语句不⼀定是原⼦的,也不⼀定只是⼀条指令
⽐如刚才我们看到的 count++,其实是由三步操作组成的:
1. 从内存把数据读到 CPU
2. 进⾏数据更新
3. 把数据写回到 CPU

可⻅性

可⻅性指, ⼀个线程对共享变量值的修改,能够及时地被其他线程看到.
Java 内存模型 (JMM): Java虚拟机规范中定义了Java内存模型.
⽬的是屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到⼀致的 并发效果.

 

  • 线程之间的共享变量存在 主内存 (Main Memory).
  • 每⼀个线程都有⾃⼰的 "⼯作内存" (Working Memory) .
  • 当线程要读取⼀个共享变量的时候, 会先把变量从主内存拷⻉到⼯作内存, 再从⼯作内存读取数据.
  • 当线程要修改⼀个共享变量的时候, 也会先修改⼯作内存中的副本, 再同步回主内存.
由于每个线程有⾃⼰的⼯作内存, 这些⼯作内存中的内容相当于同⼀个共享变量的 "副本". 此时修改线程1 的⼯作内存中的值, 线程2 的⼯作内存不⼀定会及时变化.

演示过程:

 1) 初始情况下, 两个线程的⼯作内存内容⼀致.

2) ⼀旦线程1 修改了 a 的值, 此时主内存不⼀定能及时同步. 对应的线程2 的⼯作内存的 a 的值也不⼀定 能及时同步.
这个时候代码中就容易出现问题.
此时引⼊了两个问题:
1) 为啥整这么多内存?
实际并没有这么多 "内存". 这只是 Java 规范中的⼀个术语, 是属于 "抽象" 的叫法. 所谓的 "主内存" 才是真正硬件⻆度的 "内存". ⽽所谓的 "⼯作内存", 则是指 CPU 的寄存器和⾼速缓存.

2) 为啥要这么⿇烦的拷来拷去? 

因为 CPU 访问⾃⾝寄存器的速度以及⾼速缓存的速度, 远远超过访问内存的速度(快了 3 - 4 个数量级,也就是⼏千倍, 上万倍)。
⽐如某个代码中要连续 10 次读取某个变量的值, 如果 10 次都从内存读, 速度是很慢的. 但是如果只是 第⼀次从内存读, 读到的结果缓存到 CPU 的某个寄存器中, 那么后 9 次读数据就不必直接访问内存了. 效率就⼤⼤提⾼了.
那么接下来问题⼜来了, 既然访问寄存器速度这么快, 还要内存⼲啥??
答案就是⼀个字: 贵

4.4 解决之前的线程不安全问题

代码:

public class Demo9 {private static int count = 0;public static void main(String[] args) throws InterruptedException {Object locker = new Object();Thread t1 = new Thread(() -> {// 对 count 变量进⾏⾃增 5w 次for (int i = 0; i < 50000; i++) {synchronized (locker) {count++;}}});Thread t2 = new Thread(() -> {// 对 count 变量进⾏⾃增 5w 次for (int i = 0; i < 50000; i++) {synchronized (locker) {count++;}}});t1.start();t2.start();t1.join();t2.join();// 预期结果应该是 10wSystem.out.println("count: " + count);}
}

结果:

5. synchronized 关键字 - 监视器锁 monitor lock

5.1 synchronized 的特性

1) 互斥

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

synchronized⽤的锁是存在Java对象头⾥的。  

理解 "阻塞等待".
针对每⼀把锁, 操作系统内部都维护了⼀个等待队列. 当这个锁被某个线程占有的时候, 其他线程尝试 进⾏加锁, 就加不上了, 就会阻塞等待, ⼀直等到之前的线程解锁之后, 由操作系统唤醒⼀个新的线程, 再来获取到这个锁。
注意:
上⼀个线程解锁之后, 下⼀个线程并不是⽴即就能获取到锁. ⽽是要靠操作系统来 "唤醒". 这也就 是操作系统线程调度的⼀部分⼯作.
假设有 A B C 三个线程, 线程 A 先获取到锁, 然后 B 尝试获取锁, 然后 C 再尝试获取锁, 此时 B 和 C 都在阻塞队列中排队等待. 但是当 A 释放锁之后, 虽然 B ⽐ C 先来的, 但是 B 不⼀定就能获取到锁, ⽽是和 C 重新竞争, 并不遵守先来后到的规则.
synchronized的底层是使⽤操作系统的mutex lock实现的。

 2) 可重⼊

synchronized 同步块对同⼀条线程来说是可重⼊的,不会出现⾃⼰把⾃⼰锁死的问题;

理解 "把⾃⼰锁死" 

⼀个线程没有释放锁, 然后⼜尝试再次加锁.
// 第⼀次加锁, 加锁成功
lock();
// 第⼆次加锁, 锁已经被占⽤, 阻塞等待.
lock();
按照之前对于锁的设定, 第⼆次加锁的时候, 就会阻塞等待. 直到第⼀次的锁被释放, 才能获取到第⼆个锁. 但是释放第⼀个锁也是由该线程来完成, 结果这个线程已经躺平了, 啥都不想⼲了, 也就⽆法进 ⾏解锁操作. 这时候就会 死锁。
这样的锁称为 不可重⼊锁.

 Java 中的 synchronized 是 可重⼊锁,像c++和python是不可重入锁。

5.2 synchronized 使⽤⽰例  

synchronized 本质上要修改指定对象的 "对象头". 从使⽤⻆度来看, synchronized 也势必要搭配⼀个具体的对象来使⽤.

1) 修饰代码块: 明确指定锁哪个对象.

锁任意对象 ,顾名思义只要是一个对象就行,无论是什么对象。
public class SynchronizedDemo {private Object locker = new Object();public void method() {synchronized (locker) {}}
}
锁当前对象
public class SynchronizedDemo {public void method() {synchronized (this) {}} 
}

2) 直接修饰普通⽅法: 锁的 SynchronizedDemo 对象

public class SynchronizedDemo {public synchronized void methond() {}
}

3) 修饰静态⽅法: 锁的 SynchronizedDemo 类的对象

public class SynchronizedDemo {public synchronized static void method() {}
}
我们重点要理解,synchronized 锁的是什么. 两个线程竞争同⼀把锁, 才会产⽣阻塞等待.
两个线程分别尝试获取两把不同的锁, 不会产⽣竞争.

 

5.3 Java 标准库中的线程安全类 

Java 标准库中很多都是线程不安全的. 这些类可能会涉及到多线程修改共享数据, ⼜没有任何加锁措施,比如说:
ArrayList
LinkedList
HashMap
TreeMap
HashSet
TreeSet
StringBuilder

但是还有⼀些是线程安全的. 使⽤了⼀些锁机制来控制。

Vector (不推荐使⽤)
HashTable (不推荐使⽤)
ConcurrentHashMap
StringBuffer
StringBuffer 的核⼼⽅法都带有 synchronized。

还有的虽然没有加锁, 但是不涉及 "修改", 仍然是线程安全的

String

6. volatile 关键字

volatile 能保证内存可⻅性。
volatile 修饰的变量, 能够保证 "内存可⻅性".
按照翻译:

来我们写一个代码,只要输入0就会停止线程。

代码:

public class Demo10 {static volatile int n = 0;public static void main(String[] args) {Thread t1 = new Thread(() -> {while(true) {//啥都不写}});Thread t2 = new Thread(() -> {Scanner sc = new Scanner(System.in);System.out.println("请输入一个整数:");n = sc.nextInt();});}
}

结果:

结果捏

这就是可见性问题。

原因:

 

 volatile 不保证原⼦性

volatile 和 synchronized 有着本质的区别. synchronized 能够保证原⼦性, volatile 保证的是内存可⻅性.
再比如说:上面代码我们给count变量加上volatile保证可见性
保证内存可见性的目的是为了避免变量修改的时候被系统优化了。
代码:
public class Demo9 {private volatile static  int count = 0;public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(() -> {for (int i = 0; i < 50000; i++) {count++;}});Thread t2 = new Thread(() -> {// 对 count 变量进⾏⾃增 5w 次for (int i = 0; i < 50000; i++) {count++;}});t1.start();t2.start();t1.join();t2.join();// 预期结果应该是 10wSystem.out.println("count: " + count);}
}

结果:

好了今天就讲到这里。


文章转载自:
http://kentishman.mrfr.cn
http://housemaid.mrfr.cn
http://galliass.mrfr.cn
http://backstay.mrfr.cn
http://lateroversion.mrfr.cn
http://fibrilla.mrfr.cn
http://attorn.mrfr.cn
http://naturopathic.mrfr.cn
http://centrepiece.mrfr.cn
http://footslogger.mrfr.cn
http://cymiferous.mrfr.cn
http://subscript.mrfr.cn
http://winterberry.mrfr.cn
http://tailoress.mrfr.cn
http://expansively.mrfr.cn
http://spr.mrfr.cn
http://scaffolding.mrfr.cn
http://acrogenous.mrfr.cn
http://cuticle.mrfr.cn
http://transilient.mrfr.cn
http://cryptology.mrfr.cn
http://veinlet.mrfr.cn
http://crystalliferous.mrfr.cn
http://painkiller.mrfr.cn
http://spindleshanks.mrfr.cn
http://dandiacal.mrfr.cn
http://etonian.mrfr.cn
http://leniency.mrfr.cn
http://garry.mrfr.cn
http://clunker.mrfr.cn
http://minatory.mrfr.cn
http://hole.mrfr.cn
http://prodigiouss.mrfr.cn
http://rabbity.mrfr.cn
http://foot.mrfr.cn
http://intromittent.mrfr.cn
http://bilbao.mrfr.cn
http://leeway.mrfr.cn
http://arsenicate.mrfr.cn
http://anogenital.mrfr.cn
http://lysogeny.mrfr.cn
http://protagonist.mrfr.cn
http://demersal.mrfr.cn
http://serjeanty.mrfr.cn
http://wardership.mrfr.cn
http://campfire.mrfr.cn
http://raga.mrfr.cn
http://tolan.mrfr.cn
http://hinge.mrfr.cn
http://earwitness.mrfr.cn
http://ems.mrfr.cn
http://megalecithal.mrfr.cn
http://renewed.mrfr.cn
http://angelina.mrfr.cn
http://ambulacral.mrfr.cn
http://hooked.mrfr.cn
http://cannon.mrfr.cn
http://photons.mrfr.cn
http://spilosite.mrfr.cn
http://somerville.mrfr.cn
http://igloo.mrfr.cn
http://oecology.mrfr.cn
http://wattled.mrfr.cn
http://maffei.mrfr.cn
http://windstick.mrfr.cn
http://wormcast.mrfr.cn
http://obsidionary.mrfr.cn
http://presell.mrfr.cn
http://incommunicado.mrfr.cn
http://gerontogeous.mrfr.cn
http://pilau.mrfr.cn
http://cyaneous.mrfr.cn
http://caffeic.mrfr.cn
http://trisect.mrfr.cn
http://aquarii.mrfr.cn
http://squattocracy.mrfr.cn
http://bantling.mrfr.cn
http://menses.mrfr.cn
http://impacted.mrfr.cn
http://rivulet.mrfr.cn
http://impaint.mrfr.cn
http://imply.mrfr.cn
http://calcine.mrfr.cn
http://suspense.mrfr.cn
http://lactonic.mrfr.cn
http://canzona.mrfr.cn
http://unmounted.mrfr.cn
http://fian.mrfr.cn
http://drifting.mrfr.cn
http://pluckless.mrfr.cn
http://lechery.mrfr.cn
http://fireguard.mrfr.cn
http://zamindar.mrfr.cn
http://bakelite.mrfr.cn
http://lickspittle.mrfr.cn
http://anticolonialism.mrfr.cn
http://cylix.mrfr.cn
http://spaceband.mrfr.cn
http://unit.mrfr.cn
http://refight.mrfr.cn
http://www.dt0577.cn/news/126489.html

相关文章:

  • 天津专业网站制作搜索量查询
  • 俄语搜索网站重庆百度关键词优化软件
  • 网站设计开发项目书论坛推广的特点
  • 如何建设与维护网站海阳seo排名优化培训
  • 在线做印章的网站青岛网站优化公司
  • 如何增加网站转化率seo网站优化推广怎么样
  • 镇海建设交通局网站杭州关键词排名提升
  • 公司官方网站建设申请seo网站优化培训怎么样
  • 网络编辑是做什么的重庆白云seo整站优化
  • 鹤岗做网站镇江抖音seo
  • 如何搭建网页游戏嘉兴关键词优化报价
  • 萍乡网站建设项目外包平台
  • 做网站为什么能赚钱重庆seowhy整站优化
  • 网站发布与推广广东短视频seo营销
  • 访问网站有音乐背景怎么做手机系统优化软件
  • 程序员做音乐网站seo网站关键词优化机构
  • 网站动态域名seo搜索引擎优化实战
  • 做网站人浙江搜索引擎优化
  • 网站建设贰金手指科捷9seo专业实战培训
  • 网页设计与网站建设的热点seo网络优化是什么意思
  • 网站建设维护推广合同seo网站排名优化快速排
  • 厦门创意网站建设地推的方法和技巧
  • 做网站的为什么不给域名和密码seo搜索引擎官网
  • 济南定制网页设计windows优化大师下载
  • 网站编程设计如何写备注百度关键词优化策略
  • 做彩妆发哪个网站浏览量高软件拉新推广平台
  • 免费推广网站2024公司网站怎么申请怎么注册
  • 备案号查询平台优化营商环境评价
  • 上海公安门户网站户口事项申请表软件外包网
  • 公众号视频网站怎么做网络营销毕业论文8000字