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

java保证多线程的执行顺序

1. java多线程环境中,如何保证多个线程按指定的顺序执行呢?

1.1 通过thread的join方法保证多线程的顺序执行, wait是让主线程等待

比如一个main方法里面先后运行thread1,,thread2,thread3,那么thread1.start()之后,运行thread1.join(),这是会让主线程mian等待新的线程thread1执行完了,再执行主线程mian下面的代码,thread1.join()是然主线程main wait。

package com.java.yj;

/**
 * Created by yejian on 2018/7/9.
 */
public class MultiThread {
    public static void main(String[] args) throws InterruptedException {
        Thread thread1 = new Thread(new Thread1());
        thread1.start();
        thread1.join();
        Thread thread2 = new Thread(new Thread2());
        thread2.start();
        thread2.join();
        Thread thread3 = new Thread(new Thread3());
        thread3.start();

    }

    public static class Thread1 implements Runnable{
        @Override
        public void run() {
            System.out.println("Thread1");
        }
    }

    public static class Thread2 implements Runnable{
        @Override
        public void run() {
            System.out.println("Thread2");
        }
    }

    public static class Thread3 implements Runnable{
        @Override
        public void run() {
            System.out.println("Thread3");
        }
    }

}

1.2 ExecutorService executor = Executors.newSingleThreadExecutor()

java5以后提供的一个多线程操作方法,创建一个只有一个线程的线程池操作,会创建一个线程队列,按FIFO的顺序执行里面的线程。

package com.java.yj;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by yejian on 2018/7/9.
 */
public class MultiThread2 {
    public static void main(String[] args) throws InterruptedException {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        executor.submit(new Thread1());
        executor.submit(new Thread2());
        executor.submit(new Thread3());
        executor.shutdown();
    }

    public static class Thread1 implements Runnable{
        @Override
        public void run() {
            System.out.println("Thread1");
        }
    }

    public static class Thread2 implements Runnable{
        @Override
        public void run() {
            System.out.println("Thread2");
        }
    }

    public static class Thread3 implements Runnable{
        @Override
        public void run() {
            System.out.println("Thread3");
        }
    }


}

2. java中的volatile和synthronized

2.1JMM-java memory model

解决并发过程中如何处理可见性,原子性,有序性的问题
runnable ,thread。
并发编程中的2个关键问题:

a. 线程间如何通信 --wait() notify() notifyAll()
a) 共享内存 -隐式通信
b) 消息传递 - 显示通信

b. 线程之间如何同步
在共享内存的并发模型中,同步是显示做的; synchronized
在消息传递的并发模型中,由于小时发送必须在消息接受之前,所以同步是隐式的

2.2. 定位内存可见性问题

什么对象是内存共享的 ,什么不是,堆内存的对象,java虚拟机栈

JMM定义了线程和主内存之间的一个关系。线程之间通讯,必须通过主内存通讯。

volatile、synchronized
volatile 功能,声明了volatile的变量,进行写操作的时候,jvm会向处理器发送一条Lock的前缀指令,会把这个变量所在缓存行的数据写回到系统内存。
在多处理器的情况下,保证各个处理器缓存一致性的特点,会实现缓存一致性协议。改变了值的volatile变量,在其他行程被指为失效状态其他线程要使用这个变量,需要重新到驻村里面去取。

synchronized:可重入锁、互斥性、可见性
volatile 可以做到原子性,可见性,不能做到复合操作的原子性

比如: volatile int i;
i++ 读取i的值,给i加1,把新的值赋值给i,这个i++操作在多线程环境下是无法保证原子性的

synchronized后面锁定的对象,可以是一个类对象,也可以是一个成员变量。
第一个线程进来调用monitorener 和monitorexit实现,获取对象的监视器,释放对象监视器
后续进程过来,如果monitor还没有释放,那么他获取不到这个对象的monitor,会放到一个对列里面:synthronizedQueue。 等到对象的锁释放了,通知synthronizedQueue出队列,获取那个monitor。

3. Lock和synchronized

Lock是java5以后出现的,在juc包: java.util.concurrentlocks

3.1 synthronized的锁什么时候释放

    1.1 获取锁的线程执行完了该代码块
    1.2 线程出现异常

3.2 synchronized的缺陷

2.1 读写冲突

3.3 Lock可以主动去释放锁,而synchronized是被动的

ReadWriteLock
ReadLock
WriteLock
ReenterantLock可重入锁
可中断锁
公平锁 等待一个锁的实际越长,获取这个锁的几率越高
ReenterantReadWriteLock 可重入读写锁
Lock是java里面的一个接口,有丰富的实现,而synchronized是java的一个关键字,是一个内置的功能

竞争资源激烈的情况,Lock性能优于synchronized,但是jdk7,8对synchronized做了很多优化,性能差异不大。

转载于:https://www.cnblogs.com/james0/p/9280144.html

相关文章:

  • php 文本显示一部分_使用简单,功能全面的 PHP 命令行应用库
  • jzoj4196 二分图计数 解题报告(容斥原理)
  • 华为上半年手机销量_国产手机上半年销量出炉:小米华为所向无敌
  • Python2与Python3区别
  • 计算混响时间的意义_计算你房间的混响时间
  • cordova打开文件_cordova插件之下载文件并打开
  • Fragment切换返回
  • kylin 大数据架构_Kylin对大数据量的多维分析
  • 17-----案例
  • l130 华大低功耗mcu_HC32L110C6PA HC32L110C6UA 华大超低功耗 Cortex-M0+ 32位MCU
  • springmvc拦截器对请求参数解密_springMvc使用拦截器自定义处理参数
  • 2017-2018 ACM-ICPC Northern Eurasia (Northeastern European Regional) Contest (NEERC 17) 日常训练...
  • 2.6map映照容器
  • mysql_fetch_row ()出现段错误_高能:燕郊出现虚假地铁站公示牌,很多人信以为真...
  • marquee标签详解
  • [分享]iOS开发 - 实现UITableView Plain SectionView和table不停留一起滑动
  • CSS实用技巧
  • iBatis和MyBatis在使用ResultMap对应关系时的区别
  • mysql常用命令汇总
  • PaddlePaddle-GitHub的正确打开姿势
  • Python学习之路13-记分
  • vue-cli3搭建项目
  • 不用申请服务号就可以开发微信支付/支付宝/QQ钱包支付!附:直接可用的代码+demo...
  • 基于Dubbo+ZooKeeper的分布式服务的实现
  • 名企6年Java程序员的工作总结,写给在迷茫中的你!
  • 前端设计模式
  • 如何使用 OAuth 2.0 将 LinkedIn 集成入 iOS 应用
  • 深度学习入门:10门免费线上课程推荐
  • Linux权限管理(week1_day5)--技术流ken
  • #git 撤消对文件的更改
  • #HarmonyOS:软件安装window和mac预览Hello World
  • #Java第九次作业--输入输出流和文件操作
  • (1)常见O(n^2)排序算法解析
  • (2009.11版)《网络管理员考试 考前冲刺预测卷及考点解析》复习重点
  • (C语言)逆序输出字符串
  • (Java实习生)每日10道面试题打卡——JavaWeb篇
  • (LNMP) How To Install Linux, nginx, MySQL, PHP
  • (译)2019年前端性能优化清单 — 下篇
  • (转)C#调用WebService 基础
  • (转)h264中avc和flv数据的解析
  • (轉貼) UML中文FAQ (OO) (UML)
  • *** 2003
  • .【机器学习】隐马尔可夫模型(Hidden Markov Model,HMM)
  • .Net Attribute详解(上)-Attribute本质以及一个简单示例
  • .NET Framework 4.6.2改进了WPF和安全性
  • .NET MAUI学习笔记——2.构建第一个程序_初级篇
  • .Net Remoting(分离服务程序实现) - Part.3
  • .NET/C# 项目如何优雅地设置条件编译符号?
  • .NET关于 跳过SSL中遇到的问题
  • .net实现头像缩放截取功能 -----转载自accp教程网
  • .NET业务框架的构建
  • ::前边啥也没有
  • @ModelAttribute使用详解
  • @require_PUTNameError: name ‘require_PUT‘ is not defined 解决方法
  • [ C++ ] STL---string类的模拟实现