JAVA - 线程

创建线程的方式

1.继承 Thread 重写 run()方法

public class thread extends Thread {

    @Override
    public void run() {
        System.out.println("== thread run()==");
    }
    public static void main(String[] args) {
        thread thread = new thread();
        thread.start();
    }
    
}

2.实现Runnable接口,重写run()方法。

public class runnable implements Runnable {

    @Override
    public void run() {
        System.out.println("==runnable run() =="+Thread.currentThread().getName());
    }

    public static void main(String[] args) {
        runnable run = new runnable();
        Thread th = new Thread(run);
        th.start();
    }
}

3.实现Callable接口,重写call(),有返回值的线程体。

public class callable implements Callable {
    @Override
    public Object call() throws Exception {
        System.out.println("== callable call()==");
        return "callable";
    }

    public static void main(String[] args) {
        callable call = new callable();
        FutureTask futureTask = new FutureTask(call);
        Thread thread = new Thread(futureTask);
        thread.start();
        try {
            Object o = futureTask.get();
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }

}

有返回值的任务必须实现 Callable 接口,无返回值的任务必须 Runnable 接口。执行 Callable 任务后,可以获取一个 Future 的对象,在该对象上调用 get 就可以获取到 Callable 任务 返回的 Object 了,FutureTask 是 实现了RunnableFuture ,RunnableFuture 接口继承了Runnable和Future。

生命周期

线程被创建执行后,不是一启动就进入执行状态,也不是一直处于执行状态。线程的生命周期可以分为五个部分。

创建(new)、就绪(runnable)、运行(running)、阻塞(blocked)、死亡(dead)。当线程启动后,不会一直占有着CPU独自运行,线程会在运行和阻塞中不断切换。

1.创建new

当使用new 来创建一个线程时,该线程处于创建状态,此时由JVM分配内存并初始化成员变量。

2.就绪Runnable

当线程对象调用start()方法后,该线程处于就绪状态,等待调度运行。

3.运行Running

当处于就绪状态的线程获取到CPU,开始执行run()方法的线程体时,该线程处于运行状态。

4.阻塞Blocked

线程因为某种原因放弃CPU使用权,让出时间片,暂时停止运行时,该线程处于阻塞状态。

阻塞情况分为几种:

4.1等待阻塞(wait - 等待队列)

运行的线程执行wait()方法后,该线程会被JVM,放到等待队列中(waitting queue)。

4.2同步阻塞(lock - 锁池)

比如运行的线程在获取同步锁时,若该同步锁被其他线程占用,则该线程会被JVM放到锁池中(lock pool)。

4.3其他阻塞(sleep/join)

运行的线程执行sleep(long)/join()方法时,该线程会被JVM置为阻塞状态。(I/O请求之类的)

5.死亡dead

死亡状态有以下几种情况

5.1正常方法结束

run()/call()方法结束。

5.2异常

抛出未被捕获的Exception or Error

5.3stop

调用该线程的stop()方法。小心给自己弄出个死锁。

sleep 与 wait 区别

1.  sleep()方法,属于 Thread 类中的。而 wait()方法,则是属于 Object 类中的。

2. sleep()方法导致了程序暂停执行指定的时间,让出 cpu 该其他线程,但是他的监控状态依然 保持者,当指定的时间到了又会自动恢复运行状态。

3. 在调用 sleep()方法的过程中,线程不会释放对象锁。

4. 而当调用 wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此 对象调用 notify()方法后本线程才进入对象锁定池准备获取对象锁进入运行状态。

start 与 run 区别

1. start()方法来启动线程,真正实现了多线程运行。这时无需等待 run 方法体代码执行完毕, 可以直接继续执行下面的代码。

2. 通过调用 Thread 类的 start()方法来启动一个线程, 这时此线程是处于就绪状态, 并没有运行。

3. 方法 run()称为线程体,它包含了要执行的这个线程的内容,线程就进入了运行状态,开始运 行 run 函数当中的代码。 Run 方法运行结束, 此线程终止。然后 CPU 再调度其它线程。

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值