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

黑龙江省建设会计协会网站杭州微网站开发公司电话

黑龙江省建设会计协会网站,杭州微网站开发公司电话,如何开发一个微网站,软文代写新闻稿文章目录一.线程安全的概念1.1 线程安全的概念1.2 线程不安全的原因1.3 解决线程不安全二.synchronized-monitor lock(监视器锁)2.1 synchronized的特性(1)互斥(2)刷新内存(3)可重入2.2 synchronied使用方法1.直接修饰普通方法:2.修饰静态方法:3.修饰代码块:三.死锁3.1死锁的情… 文章目录一.线程安全的概念1.1 线程安全的概念1.2 线程不安全的原因1.3 解决线程不安全二.synchronized-monitor lock(监视器锁)2.1 synchronized的特性(1)互斥(2)刷新内存(3)可重入2.2 synchronied使用方法1.直接修饰普通方法:2.修饰静态方法:3.修饰代码块:三.死锁3.1死锁的情况3.2 死锁的四个必要条件1.互斥使用2.不可抢占3.请求和保持4.循环等待3.3解决死锁的办法四.volatile 关键字五. wait和notify5.1 wait()方法5.2 notify()方法一.线程安全的概念 先来看一段代码 class Counter{public int count 0;public void add(){count;}} public class Thread14 {public static void main(String[] args) throws InterruptedException {Counter counter new Counter();Thread t1 new Thread(()-{for (int i 0; i 50000; i) {counter.add();}});Thread t2 new Thread(() -{for (int i 0; i 50000; i) {counter.add();}});t1.start();t2.start();t1.join();t2.join();System.out.println(count counter.count);} } 可以看到结果是不确定的 1.1 线程安全的概念 先来说一下非线程安全的概念:非线程安全主要是指多个线程对同一个对象中的同一个实例变量进行操作时会出现值被更改、值不同步的情况进而影响程序的执行流程。 则线程安全:如果多线程环境下代码运行的结果是符合我们预期的即在单线程环境应该的结果则说这个程序是线程安全的。 1.2 线程不安全的原因 先解释上述线代码程不安全的原因 如果两个线程并发执行count,此时就相当于两组load add save进行执行,此时不同的线程调度顺序就可能会产生一些结果上的差异 由于线程的抢占执行,导致当前执行到任意一个指令,线程都可能bei调度走,CPU让别的线程来执行 如下图: 导致下面的结果: 线程安全问题的原因: 1.抢占式执行,随机调度(根本原因) 2.代码结构:多个线程同时修改同一个变量 3.原子性(操作是非原子性,容易出现问题) 4.内存可见性问题(如一个线程读,一个线程改) 5.指令重排序 1.3 解决线程不安全 从原子性入手,通过加锁,把非原子的,转成原子的 加了synchronized之后,进入方法就会加锁,出了方法就会解锁,如果两个线程同时尝试加锁,此时一个能获取锁成功,另一个只能阻塞等待(BLOCKED),一直阻塞到刚才的线程解锁,当前线程才能加锁成功 二.synchronized-monitor lock(监视器锁) 2.1 synchronized的特性 (1)互斥 进入sychronized修饰的代码块,相当于加锁退出sychronizde修饰的代码块,相当于解锁 (2)刷新内存 synchronized的工作过程: 1.获得互斥锁 2.从内存拷贝变量的最新副本到工作的内存 3.执行代码 4.将更改后的共享变量的值刷新到主内存 5.释放互斥锁 (3)可重入 synchronized同步块对同一条线程来说是可重入的,不会出现自己把自己锁死的问题(自己可以再次获取自己的内部锁) 理解把自己锁死 一个线程没有释放锁,然后又尝试再次加锁 按照之前对于锁的设定,第二次加锁的时候,就会阻塞等待,而获取不到第一次的锁,就把自己锁死 2.2 synchronied使用方法 1.直接修饰普通方法: 锁的SynchronizedDemo1对象 public class SynchronizedDemo1 {public synchronized void methond() {} }2.修饰静态方法: 锁SynchronizedDemo2对象 public class SynchronizedDemo2 {public synchronized void methond() {} }3.修饰代码块: 明确指定锁哪个对象 public class SychronizedDemo{public void method(){sychronized(this){}} }锁类对象 public class SynchronizedDemo {public void method() {synchronized (SynchronizedDemo.class) {}} }三.死锁 3.1死锁的情况 1.一个线程,连续加锁两次,如果锁是不可重入锁,就会死锁 2.两个线程,两把锁,t1和t2各自先针对锁A和锁B加锁,在获取对方的锁 public class Thread15 {public static void main(String[] args) {Object lock1 new Object();Object lock2 new Object();Thread t1 new Thread(()-{synchronized (lock1){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}synchronized (lock2){System.out.println(t1把锁1和锁2都获得了);}}});Thread t2 new Thread(()-{synchronized (lock2){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}synchronized (lock1){System.out.println(t2把锁1和锁2都获得了);}};});t1.start();t2.start();} } 3.多个线程,多把锁(相当于2的一般情况) 3.2 死锁的四个必要条件 1.互斥使用 线程1拿到了锁,线程2就须等着 2.不可抢占 线程1拿到锁A之后,必须是线程1主动释放 3.请求和保持 线程1拿到锁A之后,在尝试获取锁B,A这把锁还是保持的 4.循环等待 线程1尝试获取到锁A和锁B,线程2尝试获取锁B和锁A,线程1在获取B的时候等待线程2释放B,同时线程2 在获取A的时候等待线程1释放A 3.3解决死锁的办法 给锁编号,然后指定一个固定的顺序来加锁,任意线程加把锁,都让线程遵守上述顺序,此时循环等待自然破除 对于synchronied前三个条件都是锁的基本特性,我们只能对四修改 public class Thread15 {public static void main(String[] args) {Object lock1 new Object();Object lock2 new Object();Thread t1 new Thread(()-{synchronized (lock1){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}synchronized (lock2){System.out.println(t1把锁1和锁2都获得了);}}});Thread t2 new Thread(()-{synchronized (lock1){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}synchronized (lock2){System.out.println(t2把锁1和锁2都获得了);}};});t1.start();t2.start();} } 四.volatile 关键字 volatile 和内存可见性问题密切相关 一个线程针对一个变量进行读取操作,同时另一个线程针对这个变量进行修改,此时读取到值,不一定是修改之后的值(归根结底是编译器/jvm在多线程下优化时产生了误判) 使用汇编语言解释 1.load,把内存中flag的值,读取到寄存器 2.cmp把寄存器的值和0进行比较,根据比较结果,决定下一不执行. 由于load执行速度太慢(相比于cmp来说),再加上反复load的结果都一样,JVM就不在重复load判定没人改flag值,就只读取一次就好 而给flag加上volatile关键字,告诉编译器变量是易变的,不再进行优化 class MyCounter{volatile public int flag 0; } public class Thread16 {public static void main(String[] args) {MyCounter myCounter new MyCounter();Thread t1 new Thread(() -{while (myCounter.flag 0){//循环体空着}System.out.println(t1循环结束);});Thread t2 new Thread(() -{Scanner scanner new Scanner(System.in);System.out.println(请输入一个整数:);myCounter.flag scanner.nextInt();});t1.start();t2.start();} } 结果: 五. wait和notify wait和notify可以协调线程之间的先后顺序 完成这个协调工作, 主要涉及到三个方法 wait() / wait(long timeout): 让当前线程进入等待状态.notify() / notifyAll():唤醒在当前对象上等待的线程. 注意: wait, notify, notifyAll 都是 Object 类的方法 5.1 wait()方法 wait的操作 1.先释放锁 2.在阻塞等待 3.收到通知之后,重新获取锁,并且在获取锁后,继续往下执行 wait操作需要搭配synchorized来使用 public class Thread17 {public static void main(String[] args) throws InterruptedException {Object object new Object();System.out.println(wait之前);object.wait();System.out.println(wait之后);} }无synchorized的情况 wait无参数版本,就是死等 wait带参数版本,指定了等待的最大时间 5.2 notify()方法 notify()方法是唤醒等待线程 如果有多个线程等待则有线程调度器随机挑选出一个呈 wait 状态的线程。(并没有 “先来后到”) 在notify()方法后当前线程不会马上释放该对象锁要等到执行notify()方法的线程将程序执行完也就是退出同步代码块之后才会释放对象锁。 notfiyAll()方法可以一次唤醒所有的等待线程
http://www.hkea.cn/news/14311550/

相关文章:

  • 江阴市网站建设h5开发app用什么工具好
  • 课程网站设计建设孝感建设公司网站
  • 甘肃住房和城乡建设局网站wordpress手机发布时间
  • 上海中国建设银行网站网站seo的重要性
  • 广东网站建设费用个人简历word可编辑免费
  • 网站转移空间以后ip会变化吗可道网站建设
  • 网站的网络营销方案北京给网站做系统的公司名称
  • 揭阳企业网站排名多少钱网站运营报告
  • 聊城网站建设服务好番禺怎么读
  • 销售型网站建设基本要素wordpress cos 配置
  • 学院网站建设的目的及定位宿迁哪家做网站好
  • 网站建设 技术团队介绍网址免费全自动推广平台
  • 公司门户网站建设重庆公司网站设计制作
  • 做自媒体查找素材的网站零基础学建网站
  • 企业官网网站建设报价怎么做黑客把网站余额更改
  • 三晋联盟做网站需要多钱做自媒体的上那些网站
  • 深圳营销型网站建设电话国内大型软件外包公司
  • 做货代用的网站建模网站素材
  • 购物网站线下推广方案电子商务网站推广方法和技巧
  • 自己做网站怎么编代码嘉兴网站建设定制
  • 各省住房和城乡建设厅网站app开发软件公司
  • 网站关键词怎么添加微信公众号做电影网站
  • 国内做化妆刷的比较好的网站了解当前各类网站建设价格
  • 网站怎么做来流量吗久久网招聘信息
  • 石家庄模板建站平台旅游业网站开发建设
  • 怎样创建网站数据库wap网站定位
  • 广西建设部网站网站建设英语词汇
  • 如何建立公司企业网站天津做网站的哪家好
  • 中小企业网站制作价格响应式网站设计公司
  • 中山住房和建设局网站建材行业网站建设方案