Java 的线程是通过 java.lang.Thread 类来实现的. VM 启动时会有一个由主方法所定义的线程. 可以通过创建 Thread 的实例来创建新的线程. 每个线程都是通过某个特定 Thread 对象所对应的方法 run() 来完成其操作的, 方法 run() 称为线程体. 通过调用 Thread 类的 start() 方法来启动一个线程.
在 Java 当中, 线程通常都有五种状态, 创建, 就绪, 运行, 阻塞和死亡:
第一是创建状态. 在生成线程对象, 并没有调用该对象的 start 方法, 这是线程处于创建状态.
第二是就绪状态. 当调用了线程对象的 start 方法之后, 该线程就进入了就绪状态, 但是此时线程调度程序还没有把该线程设置为当前线程, 此时处于就绪状态. 在线程运行之后, 从等待或者睡眠中回来之后, 也会处于就绪状态.
第三是运行状态. 线程调度程序将处于就绪状态的线程设置为当前线程, 此时线程就进入了运行状态, 开始运行 run 函数当中的代码.
第四是阻塞状态. 线程正在运行的时候, 被暂停, 通常是为了等待某个事件的发生 (比如说某项资源就绪) 之后再继续运行. sleep,suspend,wait 等方法都可以导致线程阻塞.
第五是死亡状态. 如果一个线程的 run 方法执行结束或者调用 stop 方法后, 该线程就会死亡. 对于已经死亡的线程, 无法再使用 start 方法令其进入就绪.
实现并启动线程有两种方法:
1, 写一个类继承自 Thread 类, 重写 run 方法. 用 start 方法启动线程
2, 写一个类实现 Runnable 接口, 实现 run 方法. 用 new Thread(Runnable target).start() 方法来启动
多线程原理: 相当于玩游戏机, 只有一个游戏机 (cpu), 可是有很多人要玩, 于是, start 是排队! 等 CPU 选中你就是轮到你, 你就 run(), 当 CPU 的运行的时间片执行完, 这个线程就继续排队, 等待下一次的 run().
调用 start() 后, 线程会被放到等待队列, 等待 CPU 调度, 并不一定要马上开始执行, 只是将这个线程置于可动行状态. 然后通过 JVM, 线程 Thread 会调用 run() 方法, 执行本线程的线程体. 先调用 start 后调用 run, 这么麻烦, 为了不直接调用 run? 就是为了实现多线程的优点, 没这个 start 不行.
1.start() 方法来启动线程, 真正实现了多线程运行. 这时无需等待 run 方法体代码执行完毕, 可以直接继续执行下面的代码; 通过调用 Thread 类的 start() 方法来启动一个线程, 这时此线程是处于就绪状态, 并没有运行. 然后通过此 Thread 类调用方法 run() 来完成其运行操作的, 这里方法 run() 称为线程体, 它包含了要执行的这个线程的内容, Run 方法运行结束, 此线程终止. 然后 CPU 再调度其它线程.
2.run() 方法当作普通方法的方式调用. 程序还是要顺序执行, 要等待 run 方法体执行完毕后, 才可继续执行下面的代码; 程序中只有主线程 -- 这一个线程, 其程序执行路径还是只有一条, 这样就没有达到写线程的目的.
记住: 多线程就是分时利用 CPU, 宏观上让所有线程一起执行 , 也叫并发
package basic;
public class ThreadTest {
public static void main(String[] args) {
Runner1 runner1 = new Runner1();
Runner2 runner2 = new Runner2();
// Thread(Runnable target) 分配新的 Thread 对象.
Thread thread1 = new Thread(runner1);
Thread thread2 = new Thread(runner2);
thread1.start(); // 执行 start,thread1 与 thread2 交叉执行
thread2.start();
//thread1.run(); // 执行 run,thread1 与 thread2 顺序执行
//thread2.run();
}
}
class Runner1 implements Runnable { // 实现了 Runnable 接口, jdk 就知道这个类是一个线程
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("进入 Runner1 运行状态 ----------" + i);
}
}
}
class Runner2 implements Runnable { // 实现了 Runnable 接口, jdk 就知道这个类是一个线程
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("进入 Runner2 运行状态 ==========" + i);
}
}
}
来源: http://www.bubuko.com/infodetail-2481337.html