多线程

一个进程中至少有1+个线程

创建线程的两种方式

继承Thread

image.png
步骤:

  1. 定义类继承Thread类;

  2. 目的是复写run方法,将要让线程运行的代码都存储到run方法中;

  3. 通过创建Thread类的子类对象,创建线程对象;

  4. 调用线程的start方法,开启线程,并执行run方法。

特点:

  • 当类去描述事物,事物中有属性和行为。如果行为中有部分代码需要被多线程执行,同时还在操作属性。就需要该类继承Thread类,那么产生该类的对象作为线程对象,可是这样做会导致,每个对象都存储一份属性数据。无法在多个线程中共享该数据。加上静态,虽然实现了共享,但是生命周期太长。

线程状态:

被创建:start()

运行:具备执行资格,同时具备执行权;

冻结:sleep(time),wait()—notify()唤醒;线程释放了执行权,同时释放执行资格;

临时阻塞状态:线程具备cpu的执行资格,没有cpu的执行权;

消亡:stop()

实现Runnable接口

image.png

步骤:

  1. 定义类实现Runnable接口。

  2. 覆盖接口中的run方法(用于封装线程要运行的代码)。

  3. 通过Thread类创建线程对象;

  4. 将实现了Runnable接口的子类对象作为实际参数传递给Thread类中的构造函数。

为什么要传递呢?因为要让线程对象明确要运行的run方法所属的对象。

5,调用Thread对象的start方法。开启线程,并运行Runnable接口子类中的run方法。
特点:

  1. 描述失误的类中封装了属性和行为,如果有部分代码被多线程所执行。同时还在操作属性,那么可以通过实现Runnable接口
    的方式。
    因为该方式是定义一个Runnable接口的子类独显,可以被多个相处所操作实现了数据的共享。
  2. 实现Runnable的接口的好处,避免了单继承的局限性。
    如果一个类明确了自己的父类,那么很遗憾,他就不可以继承Thread。因为java不支持多继承。

join

该方法也是一种阻塞,指在当前运行的A线程中加入一个新的线程B,A线程此时属于阻塞状态,要等待B线程全部运行完毕后,才能继续运行A线程。
Join方法要加在当前运行线程的代码块中,例如:

public class MyRunnable implements Runnable{
    public void run() {
        MyRunnable2 myRunnable2 = new MyRunnable2();
        Thread thread = new Thread(myRunnable2, "线程2");
        thread.start();
        for (int i = 0; i < 1000; i++) {
            System.out.println(Thread.currentThread().getName()+":"+i);
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
public class MyRunnable2 implements Runnable{
    public void run() {
        for (int i = 0; i < 1000; i++) {
            System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }
}

重入锁(对象互斥锁)

未完

Q.E.D.


如人饮水、冷暖自知