线程 多线程

java.lang.Thread 线程

  • start() 启动一个线程
  • run() 线程执行的具体代码
  • setPriority() 设置线程优先级 1-10 缺省为5
  • yield() 线程放弃当前CPU的使用权,重新进入就绪状态

Thread.currentThread().getName() 用来获取当前线程的名字

线程五种状态

  • 新建(new):线程对象仅仅创建,还未调用start()方法
  • 就绪(runnable):已调用start()方法,线程进入可运行线程池中,等待获取CPU的使用权
  • 运行(running):就绪状态的线程获取了CPU,执行程序代码
  • 阻塞(blocked):线程没有CPU的使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分为三种:
    • 等待阻塞:线程执行wait()方法,JVM会把该线程放入等待池中。
    • 同步阻塞:运行的线程在获取对象的同步锁时,该同步锁被其他线程占用。JVM把该线程放入等锁池中。
    • 其他阻塞:线程执行sleep()或join()方法,或者发出了I/O请求,JVM会把线程置为阻塞状态。当sleep()、join()结束,或者I/O处理完毕时,线程重新转入就绪状态。
  • 死亡(dead):线程执行完毕或者因异常退出了run()方法,该线程结束生命周期

    线程 多线程_第1张图片

wait() 和 sleep() 的区别

  • wait() 是Object类的方法。

    调用对象的wait()方法导致当前线程放弃对象的锁(线程暂停执行),进入对象的等待池(wait pool),只有调用对象的notify()方法(或notifyAll()方法)时才能唤醒等待池中的线程进入等锁池(lock pool),如果线程重新获得对象的锁就可以进入就绪状态

  • sleep() 是Thread类的方法。

    sleep()方法(休眠)是线程类(Thread)的静态方法,调用此方法会让当前线程暂停执行指定的时间,将执行机会(CPU)让给其他线程,但是对象的锁依然保持,因此休眠时间结束后会自动恢复(线程回到就绪状态)

简单的说就是,wait会释放程序的锁,而sleep不会释放锁。

多线程的三种方式

  • 继承Thread类,重写run()方法。通过start()启动
  • 实现Runnable接口,实现run()方法。通过new Thread(new Runnable).start()启动
  • 实现Callable接口,实现call()方法

三种方式的区别

  • 实现Runnable接口可以避免java单继承的局限性;代码能被多个线程共享,代码与数据独立;适合多个相同程序代码的线程去处理统一资源的情况
  • 继承Thread类和实现Runnable接口启动线程都是使用start()方法,然后JVM将此线程放到就绪队列中,如果有处理器可用,则执行run()方法
  • 实现Callable接口要实现call()方法,并且线程执行完后会有返回值。其他两种都是重写run()方法,没有返回值

线程安全:一个类在多线程的访问下运转一切正常,并且访问类不需要进行额外的同步处理或协调。

如何保证线程安全

  • 对变量使用volatile
  • 对程序段进行加锁(synchronized、lock)

非线程安全的集合在多线程环境下可以使用,但并不能作为多个线程共享的属性,可以作为某个线程独享的属性

你可能感兴趣的:(Java基础)