java基础及多线程

1.多线程

  1.1.进程与线程

    进程就是一个运行中的程序。

    一个进程中可以有多个线程,线程是CPU调度和分派的基本单位。我们可以理解为线程就是程序运行中的一条路径。

    java程序运行说明jvm实例存活,若jvm结束了(调用System.exit(0);),则所有线程结束

  1.2.多线程的创建及使用

    1.2.1.创建

      自定义一个类继承Thread类或实现Runnable接口

    1.2.2:两种创建多线程的区别

        继承Thread类:Thread()Thread(String name) 多个线程分别完成自己的任务

        实现Runnable接口:Thread(Runnable target) 或Thread(Runnable target, String name) 是多个线程共同完成一个任务

    1.2.3:线程的启动

      两种创建方式都是调用Thread对象的start()方法。当调用start()方法时,CPU会开启一条新线程,并在新线程上执行run()方法。

    1.2.4:线程常用方法

       currentThread:静态方法,用来获取当前线程

      getName、setName:用来获取、设置当前线程的名字

      sleep:控制线程休眠,单位为毫秒

      setDaemon:将线程设置为守护线程。线程默认是非守护线程,守护线程不能单独执行(即所有的默认结束后,守护线程也会结束)。

      join:当前线程暂停,等待加入的线程运行结束,当前线程继续执行。

  1.3:线程的同步:

      同步代码块synchronized(锁对象){需要同步的代码...}形式将访问数据的代码锁住,在同步代码块中的内容同一时间内只能一个线程执行。

         方法锁:如:public synchronized void testSyn(){}。同步非静态方法使用this作为锁,静态方法使用的是类对象本身

  1.4:线程的生命周期:

      1.新建状态(New):用new语句创建的线程对象处于新建状态,此时它和其它的java对象一样,仅仅在堆中被分配了内存 
      2.就绪状态(Runnable):当一个线程创建了以后,其他的线程调用了它的start()方法,该线程就进入了就绪状态。处于这个状态的 线程位于可运行池中,等待获得CPU的使用权 
      3.运行状态(Running): 处于这个状态的线程占用CPU,执行程序的代码 
      4.阻塞状态(Blocked): 当线程处于阻塞状态时,java虚拟机不会给线程分配CPU,直到线程重新进入就绪状态,它才有机会转到 运行状态。 
        阻塞状态分为三种情况: 
          1)、 位于对象等待池中的阻塞状态:当线程运行时,如果执行了某个对象的wait()方法,java虚拟机就回把线程放到这个对象的等待池中 
          2)、 位于对象锁中的阻塞状态,当线程处于运行状态时,试图获得某个对象的同步锁时,如果该对象的同步锁已经被其他的线程占用,JVM就会把这个线程放到这个对象的琐池中。 

          3)、 其它的阻塞状态:当前线程执行了sleep()方法,或者调用了其它线程的join()方法,或者发出了I/O请求时,就会进入这个状态中。

  1.:5:多线程间的通信:

      在同步代码中可以使用锁对象的wait()方法让当前线程等待

      使用锁对象的notify()方法可以将正在等待的线程唤醒

       如果多个线程都在等待,notify()唤醒随机1个

      notifyAll()方法可以唤醒所有在等待的线程

 

2.锁机制

  

 

3.内存的的可见性:

  3.1.共享变量在线程间的可见性

    共享变量:如果一个变量在多个线程的工作内存中都存在副本,那么这个变量就是这几个线程的共享变量。

    可见性:一个线程对共享变量值的修改,能够及时地被其他线程看到。

    Java内存模型(JMM:Java Memory Model():描述了java程序中各种变量的访问规则,以及在jvm中将变量存储到内存和从内存中读取变量这样的底层细节。

      所有的变量都存储在主线程中

      每个线程都有自己独立的工作内存,里面保存该线程使用的变量的副本(主内存中该变量的一份拷贝)

      

      特点:1.线程对共享变量的所有操作都必须在自己的工作内存中进行,不能直接从主内存中读写

           2.不同线程之间无法直接访问其他线程工作内存中的变量,线程间变量值的传递需要通过主内存来完成。

  2.2.java语言层面支持的可见性实现方式(synchronized、volatile): 

    3.2.1:指令重排序:代码书写的顺序与实际执行的顺序不同,指令的重排序是编译器或处理器为了提高程序性能而做的优化   

      2.1:编译器优化的重排序(编译器优化)

      2.2:指令级并行重排序(处理器优化)

      2.3:内存系统的重排序(处理器优化)

    3.2:as-if-serial语义:无论如何重排序,程序执行的结果应该与代码顺序执行的结果一致

       1. jvm编译器,运行时和处理器都会保证java在单线程下遵循as-if-serial语义

       2.

  

    3.2.3:synchronized实现可见性

      3.2.3.1:特性:原子性、可见性

      3.2.3.2:线程解锁前,必须把共享变量的最新值刷新到主内存中,线程加锁时,将清空工作内存中共享变量的值

      3.2.3.3:线程执行互斥代码过程:

        1.获取互斥锁;

        2.清空工作内存;

        3.从主内存拷贝变量的最新副本到工作内存;

        4.执行代码;

        5把共享变量的最新值刷新到主内存中;

        6释放互斥锁

 

    3.2.4:volatile实现可见性

      指令重排序

      

      volatile使用注意事项

      synchronized与volatile

转载于:https://www.cnblogs.com/cjcblogs/p/4737903.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值