java中线程的状态

当线程被创建并启动以后,它既不是一启动就进入了执行状态,也不是一直处于执行状态。在线程的生命周期中,有几种状态呢?在API 这个枚举中给出了六种线程状态:

这里先列出各个线程状态发生的条件,下面将会对每种状态进行详细解析:

NEW和TERMINATED状态

new状态:线程刚被创建,但是并未启动。还没调用start方法。

Terminated(终止)状态:因为run方法正常退出而死亡,或者因为没有捕获的异常终止了run方法而死亡。

测试创建线程,启动线程,线程运行完毕。处于这两个状态的线程在堆栈不会出现在堆栈信息里面。

public static void testNewAndTerminatedState() {
		Thread thread = new Thread(new Runnable() {
			@Override
			public void run() {
				System.out.println("Over Run.");
			}
		});
 
		System.out.println("State " + thread.getState() + ".");
		thread.start();
 
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
 
		System.out.println("State " + thread.getState() + ".");
	}

运行结果:


State NEW.
 
Over Run.
 
State TERMINATED.

 Runnable(运行)状态

线程可以在java虚拟机中运行的状态,可能正在运行自己代码,也可能没有,这取决于操作系统处理器。

public static void testStateRunnable() {
		IOThread simpleThread = new IOThread("IOThread");
		simpleThread.start();
 
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
 
		System.out.println("Main thread check the state is " + simpleThread.getState() + "."); // RUNNABLE
	}
 
	static class IOThread extends Thread {
 
		public IOThread(String name) {
			super(name);
		}
 
		@Override
		public void run() {
			System.out.println("In run method, state is " + getState() + "."); // RUNNABLE
			Socket socket = new Socket();
			try {
				System.out.println("Try to connect socket address which not exist...");
				socket.connect(new InetSocketAddress(
						InetAddress.getByAddress(new byte[] { (byte) 192, (byte) 168, 1, 14 }), 5678));
			} catch (UnknownHostException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				try {
					socket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

运行结果:

In run method, state is RUNNABLE.
 
Try to connect socket address which not exist...
 
Main thread check the state is RUNNABLE.

主要是测试在进入run方法之后线程的状态,以及在等待IO的时候,线程的状态。

Waiting(无限等待)

Wating状态在API中介绍为:一个正在无限期等待另一个线程执行一个特别的(唤醒)动作的线程处于这一状态。

那么我们之前遇到过这种状态吗?答案是并没有,但并不妨碍我们进行一个简单深入的了解。

 /**
	 * 线程调用wait方法,状态变成WAITING。
	 */
	public static void testStateWatingByWait() {
		Object lock = new Object();
		WaitingThread waitingThread = new WaitingThread("WaitingThread", lock);
		waitingThread.start();
 
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
 
		System.out.println("Main thread check the state is " + waitingThread.getState() + "."); // WAITING
	}
 
	static class WaitingThread extends Thread {
		private int timeout = 0;
		private Object lock;
 
		public WaitingThread(String name, Object lock) {
			this(name, lock, 0);
		}
 
		public WaitingThread(String name, Object lock, int timeout) {
			super(name);
			this.timeout = timeout;
			this.lock = lock;
		}
 
		@Override
		public void run() {
			synchronized (lock) {
				if (timeout == 0) {
					try {
						System.out.println("Try to wait.");
						lock.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				} else {
					try {
						System.out.println("Try to wait in " + timeout + ".");
						lock.wait(timeout);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
 
			System.out.println("Over thread.");
		}
	}

运行结果:

Try to wait.
 
Main thread check the state is WAITING.

Timed Waiting(计时等待) 

waiting状态,有几个方法有超时参数,调用他们将进入Timed  Waiting状态。这一状态将一直保持到超时期满或者接收到唤醒通知。带有超时参数的常用方法有Thread.sleep Object.wait

package java06;

public class test02 extends Thread {
	    public void run() {
	        for (int i = 0; i < 100; i++) {
	            if ((i) % 10 == 0) {
	                System.out.println("‐‐‐‐‐‐‐" + i);
	            }
	            System.out.print(i);
	            try {
	                Thread.sleep(1000); System.out.print(" 线程睡眠1秒!\n");
	            } catch (InterruptedException e) {
	                e.printStackTrace();
	            }
	        }
	    }

	    public static void main(String[] args) {
	        new test02().start();
	    }
	}

1.进入 TIMED_WAITING 状态的一种常见情形是调用的 sleep 方法,单独的线程也可以调用,不一定非要有协作关系。

2.为了让其他线程有机会执行,可以将Thread.sleep()的调用放线程run()之内。这样才能保证该线程执行过程中会睡眠。

3.sleep与锁无关,线程睡眠到期自动苏醒,并返回到Runnable(可运行)状态。

Blocked(锁阻)

当一个线程试图获取一个对象锁,而该对象锁被其他的线程持有,则该线程进入Blocked状态;当该线程持有锁时,该线程将变成Runnable状态。

所以我们模拟两个线程抢锁,当一个线程抢到锁之后进入sleep,sleep状态下不会释放锁,所以另外一个线程被阻塞。从堆栈信息可以看到,locked和waiting to lock都是同一个对象。

 public static void testBlockedState() {
		Object lock = new Object();
		SleepThread t1 = new SleepThread("t1", lock);
		SleepThread t2 = new SleepThread("t2", lock);
		t1.start();
		t2.start();
 
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
 
		System.out.println("Thread t1's state " + t1.getState());
		System.out.println("Thread t2's state " + t2.getState());
	}
 
	static class SleepThread extends Thread {
		private String name;
		private Object lock;
 
		public SleepThread(String name, Object lock) {
			super(name);
			this.name = name;
			this.lock = lock;
		}
 
		@Override
		public void run() {
			System.out.println("Thread:" + name + " in run.");
 
			synchronized (lock) {
				System.out.println("Thread:" + name + " hold the lock.");
 
				try {
					Thread.sleep(1000 * 1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
 
				System.out.println("Thread:" + name + " return the lock.");
			}
		}
	}

运行结果:

Thread:t2 in run.
 
Thread:t1 in run.
 
Thread:t2 hold the lock.
 
Thread t1's state BLOCKED
Thread t2's state TIMED_WAITING

这就是我的分享。

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值