Java中线程基本知识整理

来源:互联网 发布:she候鸟 知乎 编辑:程序博客网 时间:2024/06/06 07:29

1、什么是线程

线程是正在执行的程序的主体。每个计算机程序至少有一个线程,它就是运行应用程序本身的线程。在Java中,这个线程称为“main thread”,即主线程,它是以执行程序的main()这个方法开始的。在java中,每个程序都有一个以上的线程,这些线程可能连开发者自己也觉察不到,例如运行garbage collection和编译java bytecode成机器指令之类的线程。

2、线程的启动

  • 继承Thread类
  • 实现Runnable接口
  • 应用程序可以使用Executor框架来创建线程池

实现Runnable接口这种方式更受欢迎,因为这不需要继承Thread类。在应用设计中已经继承了别的对象的情况下,这需要多继承(而Java不支持多继承),只能实现接口。同时,线程池也是非常高效的,很容易实现和使用。

线程的启动有两种方式:
(1)利用Thread类的子类

public class DemoThread extends Thread {    public DemoThread() {        super("DemoThread");    }    public void run() {        //Code    }}demoThread.start();

(2)利用Runnable接口

public class DemoRunnable implements Runnable {    public void run() {        //Code    }}new Thread(demoRunnable).start();

3、线程的暂停

暂停线程使用sleep函数,sleep()方法用来阻塞线程一定时间,这个时间可以自己来指定。

可参看:sleep()与wait()之间的不同

4、线程共享互斥

参考:java中synchronized用法基本总结

5、线程的协调

(1)wait set
所有实例都有一个wait set,wait set是一个执行该实例的wait方法时操作停止的线程的集合。当执行wait方法时,就会进入wait set这个休息室,除非发生下面其中一种情况,否则线程会永远被留在wait set里面。

  • 有其他线程以notify方法唤醒该线程
  • 有其他线程以notifyAll方法唤醒该线程
  • 其他线程以interrupt方法唤醒该线程

(2)wait方法的使用

Object LOCK = new Object();synchronized(LOCK) {       LOCK.wait(); // LOCK is not held}

执行上面代码,目前的线程会暂停执行,进入LOCK实例的wait set,即线程在LOCK上面wait

synchronized(this) {       wait();}

上面执行wait方法的线程会进入this的wait set,就变成了this上的wait。

另外,执行wait方法,线程需要首先获取锁定,当线程进入wait set时,就会释放该实例的锁定。

(3)notify方法的使用
使用notify方法就可以从wait set里面抓出一个线程将其唤醒

synchronized(LOCK) {       LOCK.notify();}

它会从LOCK的wait set里的线程抓出一个线程将它唤醒。被唤醒的线程就会退出wait set。另外,线程必须调用该实例的锁定,才能执行notify方法。

(4)notifyAll方法的使用
使用notifyAll方法时,会将所有在wait set里的线程都取出唤醒。

synchronized(LOCK) {       LOCK.notifyAll();}

它会唤醒所有留在实例this的wait set里面的线程

对于他们的基本使用可以看看文章Object中的wait,notify,notifyAll基本使用

下面来总结一下它们的作用:
wait,notify,notifyAll都是Object类的方法,不是Thread里面的方法。

  • obj.wait()把现在的线程放在obj的wait set中。
  • obj.notify()从obj的wait set里面唤醒一个线程。
  • obj.notifyAll()是唤醒所有obj的wait set里面的线程。

最后放一张线程状态转移图。

这里写图片描述

参考书籍:java多线程设计模式

0 0