zoukankan      html  css  js  c++  java
  • java多线程基础篇-01

    1. 第一种继承Thread类 重写run方法

    2. 第二种实现Runnable接口,重写run方法

    3. 第三种使用匿名内部类方式

     System.out.println("-----多线程创建开始-----");

     Thread thread = new Thread(new Runnable() {

    public void run() {

    for (int i = 0; i< 10; i++) {

    System.out.println("i:" + i);

    }

    }

    });

     thread.start();

     System.out.println("-----多线程创建结束-----");

    使用实现实现Runnable接口好,原因实现了接口还可以继续继承,继承了类不能再继承。

    常用线程api方法

    start()

    启动线程

    currentThread()

    获取当前线程对象

    getID()

    获取当前线程ID      Thread-编号  该编号从0开始

    getName()

    获取当前线程名称

    sleep(long mill)

    休眠线程

    Stop()

    停止线程,

    常用线程构造函数

    Thread()

    分配一个新的 Thread 对象

    ThreadString name

    分配一个新的 Thread对象,具有指定的 name正如其名

    ThreadRunable r

    分配一个新的 Thread对象

    ThreadRunable r, String name

    分配一个新的 Thread对象

    线程运行状态

     线程从创建、运行到结束总是处于下面五个状态之一:新建状态、就绪状态、运行状态、阻塞状态及死亡状态。

    状态

      当用new操作符创建一个线程时, 例如new Thread(r),线程还没有开始运行,此时线程处在新建状态。 当一个线程处于新生状态时,程序还没有开始运行线程中的代码

    就绪状态

    一个新创建的线程并不自动开始运行,要执行线程,必须调用线程的start()方法。当线程对象调用start()方法即启动了线程,start()方法创建线程运行的系统资源,并调度线程运行run()方法。当start()方法返回后,线程就处于就绪状态。

         处于就绪状态的线程并不一定立即运行run()方法,线程还必须同其他线程竞争CPU时间,只有获得CPU时间才可以运行线程。因为在单CPU的计算机系统中,不可能同时运行多个线程,一个时刻仅有一个线程处于运行状态。因此此时可能有多个线程处于就绪状态。对多个处于就绪状态的线程是由Java运行时系统的线程调度程序(thread scheduler)来调度的。

    运行状态

    当线程获得CPU时间后,它才进入运行状态,真正开始执行run()方法.

    阻塞状态

        线程运行过程中,可能由于各种原因进入阻塞状态:
            1>线程通过调用sleep方法进入睡眠状态;
            2>线程调用一个在I/O上被阻塞的操作,即该操作在输入输出操作完成之前不会返回到它的调用者;
            3>线程试图得到一个锁,而该锁正被其他线程持有;
            4>线程在等待某个触发条件;

    死亡状态

    有两个原因会导致线程死亡:
       1) run方法正常退出而自然死亡,
       2) 一个未捕获的异常终止了run方法而使线程猝死。
         为了确定线程在当前是否存活着(就是要么是可运行的,要么是被阻塞了),需要使用isAlive方法。如果是可运行或被阻塞,这个方法返回true; 如果线程仍旧是new状态且不是可运行的, 或者线程死亡了,则返回false. 

    join()方法

    ##join作用是让其他线程变为等待,  t1.join();// 让其他线程变为等待,直到当前t1线程执行完毕,才释放。

    thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程。比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B。

    优先级

    现代操作系统基本采用时分的形式调度运行的线程,线程分配得到的时间片的多少决定了线程使用处理器资源的多少,也对应了线程优先级这个概念。在JAVA线程中,通过一个int priority来控制优先级,范围为1-10,其中10最高,默认值为5。下面是源码(基于1.8)中关于priority的一些量和方法。

      public static void main(String[] args) {

        PrioritytThread prioritytThread = new PrioritytThread();

        Thread t1 = new Thread(prioritytThread);

        Thread t2 = new Thread(prioritytThread);

        t1.start();

        // 注意设置了优先级, 不代表每次都一定会被执行。 只是CPU调度会有限分配

        t1.setPriority(10);

        t2.start();

      }

    Yield方法

    Thread.yield()方法的作用:暂停当前正在执行的线程,并执行其他线程。(可能没有效果)

    yield()让当前正在运行的线程回到可运行状态,以允许具有相同优先级的其他线程获得运行的机会。因此,使用yield()的目的是让具有相同优先级的线程之间能够适当的轮换执行。但是,实际中无法保证yield()达到让步的目的,因为,让步的线程可能被线程调度程序再次选中。

    结论:大多数情况下,yield()将导致线程从运行状态转到可运行状态,但有可能没有效果。

    --------------------------------------------02---------------------------------------------

    synchronized 修饰方法使用锁是当前this锁。

    synchronized 修饰静态方法使用锁是当前类的字节码文件

    多线程有三大特性:原子性、可见性有序

    什么是Java内存模型:java内存模型简称jmm义了一个线程另一个线程可见。共享变量存放在主内存中,每个线程都有自己的本地内存,多个线程同时访问一个数据的时候,可能本地内存没有及时刷新到主内存,所以就会发生线程安全问题。

    Volatile 关键字的作用是变量在多个线程之间可见。使用Volatile关键字将解决线程之间可见性, 强制线程每次读取该值的时候都去“主内存”中取值。

    volatilesynchronized区别

    仅靠volatile不能保证线程的安全性。(原子性)

    ①volatile轻量级,只能修饰变量。synchronized重量级,还可修饰方法

    ②volatile只能保证数据的可见性,不能用来同步,因为多个线程并发访问volatile修饰的变量不会阻塞。

    synchronized不仅保证可见性,而且还保证原子性,因为,只有获得了锁的线程才能进入临界区,从而保证临界区中的所有语句都全部执行。多个线程争抢synchronized锁对象时,会出现阻塞。

    线程安全性

    线程安全性包括两个方面,①可见性。②原子性。 

    ThreadLocal

    ThreadLocal提高一个线程的局部变量,访问某个线程拥有自己局部变量。

     当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。

    ThreadLocal的接口方法

    ThreadLocal类接口很简单,只有4个方法,我们先来了解一下:

    void set(Object value)设置当前线程的线程局部变量的值。

    public Object get()该方法返回当前线程所对应的线程局部变量。

    public void remove()将当前线程局部变量的值删除,目的是为了减少内存的占用,该方法是JDK 5.0新增的方法。需要指出的是,当线程结束后,对应该线程的局部变量将自动被垃圾回收,所以显式调用该方法清除线程的局部变量并不是必须的操作,但它可以加快内存回收的速度。

    protected Object initialValue()返回该线程局部变量的初始值,该方法是一个protected的方法,显然是为了让子类覆盖而设计的。这个方法是一个延迟调用方法,在线程第1次调用get()或set(Object)时才执行,并且仅执行1次。ThreadLocal中的缺省实现直接返回一个null。

  • 相关阅读:
    OutputCache 缓存key的创建 CreateOutputCachedItemKey
    Asp.net Web Api源码调试
    asp.net mvc源码分析DefaultModelBinder 自定义的普通数据类型的绑定和验证
    Asp.net web Api源码分析HttpParameterBinding
    Asp.net web Api源码分析HttpRequestMessage的创建
    asp.net mvc源码分析ActionResult篇 RazorView.RenderView
    Asp.Net MVC 项目预编译 View
    Asp.net Web.config文件读取路径你真的清楚吗?
    asp.net 动态创建TextBox控件 如何加载状态信息
    asp.net mvc源码分析BeginForm方法 和ClientValidationEnabled 属性
  • 原文地址:https://www.cnblogs.com/liufei-90046109/p/11798081.html
Copyright © 2011-2022 走看看