java 线程thread_Java基础之线程Thread

在程序开发中, 一定遇到并发编程的场景, 虽然我们大部分时间并不直接使用Thread, 但是Thread是多线程的基础, 面试中也会总是被问到与线程有关的问题; 那么线程都有哪些知识呢? 最近在研究线程的源码的时候也总结了关于线程一些基本知识;

线程是什么

线程是轻量级的进程, 是操作系统调度任务到CPU的最小单元;

多线程编程的优点

1、多线程编程能够最大程度的利用多核设备上面的CPU资源, 保证任务处理的足够快, 及时响应客户端的额请求

2、线程的创建的代价比创建进程的代价小很多, 同时多线程的上下文切换也更快; 《操作系统概念 第六版》 在Solaris 2上面, 创建进程比创建线程慢30倍, 而进程的上下文切换比线程的上下文切换慢5倍;

Java中线程的状态有哪些

查看java.lang.Thread的源码有如下代码:

public enum State {

/**

* Thread state for a thread which has not yet started.

*/

NEW,

/**

* Thread state for a runnable thread. A thread in the runnable

* state is executing in the Java virtual machine but it may

* be waiting for other resources from the operating system

* such as processor.

*/

RUNNABLE,

/**

* Thread state for a thread blocked waiting for a monitor lock.

* A thread in the blocked state is waiting for a monitor lock

* to enter a synchronized block/method or

* reenter a synchronized block/method after calling

* {@link Object#wait() Object.wait}.

*/

BLOCKED,

/**

* Thread state for a waiting thread.

* A thread is in the waiting state due to calling one of the

* following methods:

*

*

{@link Object#wait() Object.wait} with no timeout

*

{@link #join() Thread.join} with no timeout

*

{@link LockSupport#park() LockSupport.park}

*

*

*

A thread in the waiting state is waiting for another thread to

* perform a particular action.

*

* For example, a thread that has called Object.wait()

* on an object is waiting for another thread to call

* Object.notify() or Object.notifyAll() on

* that object. A thread that has called Thread.join()

* is waiting for a specified thread to terminate.

*/

WAITING,

/**

* Thread state for a waiting thread with a specified waiting time.

* A thread is in the timed waiting state due to calling one of

* the following methods with a specified positive waiting time:

*

*

{@link #sleep Thread.sleep}

*

{@link Object#wait(long) Object.wait} with timeout

*

{@link #join(long) Thread.join} with timeout

*

{@link LockSupport#parkNanos LockSupport.parkNanos}

*

{@link LockSupport#parkUntil LockSupport.parkUntil}

*

*/

TIMED_WAITING,

/**

* Thread state for a terminated thread.

* The thread has completed execution.

*/

TERMINATED;

}

1、NEW: 线程还没有启动的时候, 状态就是NEW 即 新建状态

2、RUNNABLE: 当一个线程处于运行中或者等待CPU调度的时候, 状态就是 RUNNABLE状态; 有些地方也称为 就绪状态

3、BLOCKED: 当一个线程在等待别的线程释放锁资源的时候, 状态就是BLOCKED, 或者在该线程获取到锁之后, 在同步代码块里面调用了Wait方法, 这时候释放锁, 在获取到其他线程的notify或者notifyAll通知之后, 重新进入 同步代码块这段时间 该线程也是BLOCKED状态的;

4、WAITING: 当正在运行的线程调用了Object.wait()方法 或者 Thread.join()方法 或者 LockSupport.park()方法之后, 会进入到WAITING状态

5、TIMED_WAITING: 当正在运行的线程调用Object.wait(n) 或者 Thread.join(n) 或者 LockSupport.parkUntil(blocker, n) 会进入到 TIMED_WAITING 状态

6、TERMINATED: 当线程结束后, 会进入到 TERMINATED 状态.

状态转换如下, 该图中比Java的状态多了一个RUNNING状态, 来区别 线程的就绪状态 与 运行状态 更加方便读者理解;

c78f0adda7f14219249f06f37166668f.png

线程状态转换

线程状态转换之NEW

下面来看一下线程的状态转换用Java怎么实现:

如上面所述: 刚刚创建的线程处于NEW状态, 那么我们可以通过如下代码打印其状态:

Thread thread = new Thread(new Runnable() {

public void run() {

}

});

System.out.println(thread.getState());

线程状态转换之RUNNABLE

那么线程如何进入到RUNNABLE状态呢? 调用Thread的start方法即可; 我们在Runnable的实现里面增加对于当前线程状态的打印即可:

public static void main(String[] args) {

Thread thread = new Thread(new Runnable() {

public void run() {

System.out.println("线程进入:" + Thread.currentThread().getState());

}

});

System.out.println(thread.getState());

thread.start();

}

线程状态转换之TIMED_WAITING

那么线程怎么进入到TIMED_WAITING状态呢? 通过调用 sleep(n) join(n) 或者 wait(n)都可以进入到TIMED_WAITING状态:

调用Thread.sleep()

public static void main(String[] args) {

Thread thread = new Thread(new Runnable() {

public void run() {

System.out.println("线程进入:" + Thread.currentThread().getState());

try {

Thread.sleep(1000 * 60);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

});

System.out.println(thread.getState());

thread.start();

}

aa29af9b5085fb3b8c8ae43b3262974a.png

调用obj.wait(time)

public static void main(String[] args) {

Thread thread = new Thread(new Runnable() {

public void run() {

synchronized (Client.class) {

System.out.println("线程进入:" + Thread.currentThread().getState());

try {

Client.class.wait(60 * 1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

});

System.out.println(thread.getState());

thread.start();

}

5d96aac31ac2c32c2c2171c8bf0d1987.png

上图中表示: 在Client.class上面等待; 等待其他对象调用Client.class.notify()方法或者等待时间到期.

调用thread.join(time)

public static void main(String[] args) {

final Thread thread = new Thread(new Runnable() {

public void run() {

synchronized (Client.class) {

System.out.println("线程进入:" + Thread.currentThread().getState());

try {

Client.class.wait(60 * 1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("Client.class对象上等待超时");

}

}

});

System.out.println(thread.getState());

thread.start();

Thread thread2 = new Thread(new Runnable() {

public void run() {

synchronized (Client.class) {

try {

thread.join(50 * 1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("Thread1结束");

}

}

});

thread2.start();

}

847a0f28a2e6ae3e3cd8c30f5ba944fc.png

表示 第二个线程在等待第一个线程执行完成或者超时;

线程状态转换之WAITING

如果想要一个线程进入到WAITING状态, 那么只需要跟上面步骤一样, Thread.sleep()除外, 但是调用的时候不要传超时时间即可;

public static void main(String[] args) {

final Thread thread = new Thread(new Runnable() {

public void run() {

synchronized (Client.class) {

System.out.println("线程进入:" + Thread.currentThread().getState());

try {

Client.class.wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("被其他线程调用Client.class.notify()唤醒");

}

}

});

System.out.println(thread.getState());

thread.start();

Thread thread2 = new Thread(new Runnable() {

public void run() {

synchronized (Client.class) {

try {

thread.join(50 * 1000);

Client.class.notify();

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("Thread1结束");

}

}

});

thread2.start();

}

169a6f2a270bcc614a2d8907a7edffea.png

只要是没有时间的等待都会处于WAITING状态, 比如把上面代码修改一下, 换成join()也可以让线程处于 WAITING状态:

public static void main(String[] args) {

final Thread thread = new Thread(new Runnable() {

public void run() {

synchronized (Client.class) {

System.out.println("线程进入:" + Thread.currentThread().getState());

try {

Client.class.wait(50 * 1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("被其他线程调用Client.class.notify()唤醒");

}

}

});

System.out.println(thread.getState());

thread.start();

Thread thread2 = new Thread(new Runnable() {

public void run() {

synchronized (Client.class) {

try {

System.out.println("即将进入等待线程1完成的状态");

thread.join();

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("Thread1结束");

}

}

});

thread2.start();

}

如上代码表示线程2会在线程1执行结束之后再结束, 所以线程2就会进入到WATIING状态

484c71dc9d96970179ab2893370dec2b.png

线程状态转换之BLOCKED

上面已经看到, 通过调用线程的函数就可以控制线程的状态, 那么如何进入到BLOCKED状态呢?进入到BLOCKED状态, 按照上面的转换图 可以翻译为 多个线程出现竟态的时候, 其他线程会进入BLOCKED状态, 只有一个线程会在RUNNABLE状态,比如如下代码:

public static void main(String[] args) {

final Thread thread = new Thread(new Runnable() {

public void run() {

synchronized (Client.class) {

System.out.println("线程进入:" + Thread.currentThread().getState());

try {

Thread.sleep(1000 * 50);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

});

System.out.println(thread.getState());

thread.start();

Thread thread2 = new Thread(new Runnable() {

public void run() {

synchronized (Client.class) {

try {

System.out.println("即将进入等待线程1完成的状态");

thread.join();

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("Thread1结束");

}

}

});

thread2.start();

}

9e32db78f1dc96405eee65a76f3f635d.png

当然, 对于A线程调用了Object.class.wait()方法释放锁之后, 最后被其他线程调用Object.class.notify() A线程再次进入RUNNABLE之前的状态就是 BLOCKED;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值