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()方法用来阻塞线程一定时间,这个时间可以自己来指定。

4、线程共享互斥

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里面的线程

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

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

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

java 线程是什么意思 java的线程是什么_Code

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