线程状态

  1. new 新生状态
Thread t = new Thread()

线程对象一旦创建就进入到新生状态

  1. 就绪状态
    当调用 start() 方法,线程立即进入就绪状态,但不意味着立即调度执行;(调度进入运行状态)
  2. 阻塞状态
    当调用 sleep,wait 或同步锁定时,线程进入阻塞状态,就是代码不往下执行,阻塞事件解除后,重新进入就绪状态,等待 cpu 调度执行
  3. 运行状态
    进入运行状态,线程才真正执行线程体的代码块
  4. dead 死亡状态
    线程中断或者结束,一旦进入死亡状态,就不能再次启动

线程方法

方法

说明

setPriority(int newPriority)

更改线程的优先级

static void sleep(long millis)

在指定的毫秒数内让当前正在执行的线程休眠

void join()

等待该线程终止

static void yield

暂停当前正在执行的线程对象,并执行其它线程

Void interrupt()

中断线程,不要用这个方式

Boolean isAlive()

测试线程是否处于活动状态


线程停止

停止线程:

  1. 不推荐使用 stop(), destroy() 方法
  2. 建议使用一个标志位进行终止变量,当 flag = false,则终止线程运行
  3. 建议线程正常停止,利用次数,不建议死循环
public class TestStop implements Runnable{
  // 1.线程中定义线程体使用的标识
  private boolean flag = true;
  @override
  public void run(){
    // 2.线程体使用该标识
    while(flag){
      System.out.println("run....Thread");
    }
	}
  // 3.对外提供方法改变标识
  public void stop(){
    this.flag = false;
}

应用

package basic;


public class TestStop implements Runnable{
    // set a flag
    private boolean flag = true;
    @Override
    public void run() {
        int i = 0;
        while(flag){
            System.out.println("run .. Thread" + i++);
        }
    }

    // set a public method to stop Thread by changing flag
    public void stop(){
        this.flag = false;
    }

    public static void main(String[] args) {
        TestStop testStop = new TestStop();
        new Thread(testStop).start();
        for (int i = 0; i < 1000; i++) {
            System.out.println("main "+i);
            if(i == 900){
                // call stop method we wrote
                testStop.stop();
                System.out.println("this Thread stopped");
            }
        }
    }
}

线程休眠

  • sleep(时间)指定当前线程阻塞的毫秒数
  • sleep 存在异常 InterruptedException
  • sleep 时间达到后,线程进入就绪状态
  • sleep 可以模拟网络延时,倒计时等
  • 每一个对象都有一个锁,sleep 不会释放锁
  1. 模拟网络延时:放大问题的发生性
    多个用户操作同一对象
    线程不安全
package basic;

public class TestSleep implements Runnable{
    private int ticketNums = 10;
    @Override
    public void run() {
        while(true){
            if(ticketNums<=0){
                break;
            }
            // analog delay
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+" "+ ticketNums-- +" tickets");
        }
    }

    public static void main(String[] args) {
        TestDemo02 ticket = new TestDemo02();
        new Thread(ticket,"joe").start();
        new Thread(ticket,"jack").start();
        new Thread(ticket,"jenny").start();
    }
}
  1. 模拟倒计时
package basic;

import java.text.SimpleDateFormat;
import java.util.Date;

// countdown
public class TestSleep2 {
    public static void main(String[] args) {

        // print current time
        Date startTime = new Date(System.currentTimeMillis());
        int num = 0;
        while(true){
            try {
                Thread.sleep(1000);
                System.out.println(new SimpleDateFormat("HH:mm:ss").format(startTime));
                startTime = new Date(System.currentTimeMillis()); // update current time
                num++;
                if(num>=10){
                    break;
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        // countdown
        try {
            tenDown();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


    public static void tenDown() throws InterruptedException {
        int num = 10;
        while(true){
            Thread.sleep(1000);
            System.out.println(num--);
            if(num<=0){
                break;
            }
        }
    }
}

线程礼让

yield

礼让线程,让当前正在执行的线程暂停,但不阻塞;将线程从运行状态转为就绪状态

让cpu重新调度,礼让不一定成功,取决于cpu

package basic;

public class TestYield {
    public static void main(String[] args) {
        MyYield myYield = new MyYield();
        new Thread(myYield,"a").start();
        new Thread(myYield,"b").start();
    }

}
class MyYield implements Runnable{

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+" starts");
        Thread.yield();
        System.out.println(Thread.currentThread().getName()+" stops");
    }
}

合并线程 join

合并线程,待此线程执行完成后,再执行其它线程,其它线程阻塞

package basic;

public class TestJoin implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
            System.out.println("thread vip: "+i);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        // start thread
        TestJoin testJoin = new TestJoin();
        Thread thread = new Thread(testJoin);
        thread.start();

        // main thread
        for (int i = 0; i < 500; i++) {
            if(i==200){
                thread.join(); // cut in
            }
            System.out.println("main+ "+i);
        }

    }
}