您的位置:首页 > 编程语言 > Java开发

线程状态与停止、阻塞(join、yield、sleep)、基本信息、优先级JAVA174-177

2016-01-18 22:45 791 查看
来源:http://www.bjsxt.com/

一、S02E174_01线程状态与停止线程

一、线程状态



新生状态:用new关键字和Thread类或子类建立一个线程对象后,该线程对象就处于新生状态。处于新生状态的线程有自己的内存空间,通过调用start方法进入就绪状态(Runnable)

就绪状态:处于就绪状态的线程已经具备了运行条件,但还没有分配到CPU,处于线程就绪队列,等待系统为其分配CPU。等待状态并不是执行状态,当系统选定一个等待执行的Thread对象后,它就会从等待执行状态进入执行状态,系统挑选的动作称之为“CPU调度”。一旦获得CPU,线程就进入运行状态并自动调用自己的run方法

运行状态:在运行状态的线程执行自己的run方法中代码,直到调用其它方法而终止、或等待某资源而阻塞或完成任务而死亡。如果在给定的时间片内没有执行结束,就会被系统给换下来回到等待执行状态。

阻塞状态:处于运行状态的线程在某些情况下,如执行了sleep(睡眠)方法,或等待I/O设备等资源,将让出CPU并暂时停止自己的运行,进入阻塞状态。在阻塞状态的线程不能进入就绪状态,只有当引起阻塞的原因消除时,如睡眠时间已到,或等待的I/O设备空闲下来,线程便转入就绪状态,重新到就绪队列中排队等待,被系统选中后从原来停止的位置开始继续运行

死亡状态:死亡状态是线程生命周期中的最后一个阶段。线程死亡的原因有两个。一个是正常运行的线程完成了它的全部工作;另一个是线程被强制性地终止,如通过执行stop或destroy方法来终止一个线程(不推荐使用这两个方法。前者会产生异常,后者是强制终止,不会释放锁。)



二、停止线程

1、自然终止:线程体正常执行完毕

2、外部干涉:

——线程类中定义线程体使用的标识

——线程体使用该标识

——提供对外的方法改变该标识

——外部根据条件调用该方法即可

package com.test.thread.status;

public class TestStatus {
public static void main(String[] args) {
Study s = new Study();
new Thread(s).start();
//外部干涉
for (int i = 0; i < 100000; i++) {
if(50000 == i){//外部干涉
s.stop();
System.out.println("stop...-->>" + i);
}
}
}
}
class Study implements Runnable{
//线程类中定义线程体使用的标识
private boolean flag = true;

@Override
public void run() {
//线程体使用该标识
while(flag){
System.out.println("study thread...");
}
}
//对外提供方法改变标识
public void stop(){
this.flag = false;
}
}


二、S02E175_01线程阻塞1_join_yield

三、S02E176_01线程阻塞2_sleep_倒计时_网络延时

1、join:合并线程

2、yield:暂停自己的线程(static方法,暂停一下,可能下一毫秒又被调用,这由CPU决定)

3、sleep:休眠,不释放锁

——1)与时间相关:倒计时

——2)模拟网络延时

package com.test.thread.status;
/**
* join:合并线程
*/
public class TestJoin extends Thread {
public static void main(String[] args) throws InterruptedException {
TestJoin testJoin = new TestJoin();
Thread t = new Thread(testJoin);//新生状态
t.start();//就绪状态
//CPU调度 运行

for (int i = 0; i < 1000; i++) {
if(50==i){
t.join();//main阻塞,等待t执行完
}
System.out.println("main..."+i);
}
}

@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println("join..."+i);
}
}
}


package com.test.thread.status;
/**
* yield:暂停自己的线程(static方法,暂停一下,可能下一毫秒又被调用,这由CPU决定)
*/
public class TestYield extends Thread {
public static void main(String[] args) {
TestYield testYield = new TestYield();
Thread t = new Thread(testYield);
t.start();

for (int i = 0; i < 1000; i++) {
if(0==i%200){
//暂停当前线程
Thread.yield();//暂停一下,可能下一毫秒又被调用,这由CPU决定
}
System.out.println("main..."+i);
}
}

@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println("yield..."+i);
}
}
}


package com.test.thread.status;

import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 倒计时
* 1、倒数10个数,一秒内打印一个
* 2、倒计时
*/
public class TestSleep {
public static void main(String[] args) throws InterruptedException {
test1();
test2();
}
/**
* 1、倒数10个数,一秒内打印一个
* @throws InterruptedException
*/
public static void test1() throws InterruptedException{
int num = 10;
while(true){
System.out.println(num--);
Thread.sleep(1000);//暂停
if(num <= 0){
break;
}
}
}
/**
* 2、倒计时
* @throws InterruptedException
*/
public static void test2() throws InterruptedException{
Date endTime = new Date(System.currentTimeMillis() + 10*1000);
long end = endTime.getTime();
while(true){
//输出
System.out.println(new SimpleDateFormat("mm:ss").format(endTime));
//等待一秒
Thread.sleep(1000);
//构建下一秒时间
endTime = new Date(endTime.getTime() - 1000);
//10秒以内继续,否则退出
if(end-10000 > endTime.getTime()){
break;
}
}
}
}


package com.test.thread.status;
/**
* sleep模拟网络延时
* 引起并发问题
...
路人甲抢到了44
攻城狮抢到了44
...
路人甲抢到了1
攻城狮抢到了0
黄牛乙抢到了-1
*/
public class TestSleep2 {
public static void main(String[] args) {
//真实角色
Web12306 web = new Web12306();
//代理
Thread t1 = new Thread(web, "路人甲");
Thread t2 = new Thread(web, "黄牛乙");
Thread t3 = new Thread(web, "攻城狮");
t1.start();
t2.start();
t3.start();
}
}
class Web12306 implements Runnable {
private int num = 50;//1到50号
@Override
public void run(){
while(true) {
if(num <= 0){
break;//跳出循环
}
try {
Thread.sleep(500);//t1、t2、t3可能都在等待,num可能相同或为-1
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "抢到了" + num--);
}
}
}


四、S02E177_01线程基本信息_优先级



package com.test.thread.info;

public class MyThread implements Runnable {
private boolean flag = true;
private int num = 0;

@Override
public void run() {
while(flag){
System.out.println(Thread.currentThread().getName()+ "-->>" + num++);
}
}
public void stop(){
flag = !flag;
}
}


package com.test.thread.info;
/**
* Thread.currentThread
* setName()
* getName()
* isAlive
*/
public class InfoDemo {
public static void main(String[] args) throws InterruptedException {
MyThread it = new MyThread();
Thread proxy = new Thread(it,"挨踢");
proxy.setName("test");
System.out.println(proxy.getName());
System.out.println(Thread.currentThread().getName());//main

proxy.start();
System.out.println("启动后的状态:" + proxy.isAlive());
Thread.sleep(50);
it.stop();
Thread.sleep(100);//stop后,CPU不一定立即停止,休眠一下看一下效果
System.out.println("停止后的状态:" + proxy.isAlive());
}
}


package com.test.thread.info;
/**
* 优先级:概率,不是绝对的先后顺序
* MAX_PRIORITY 10
* NORM_PRIORITY    5(默认)
* MIN_PRIORITY 0
*
* setPriority()
* getPriority()
*/
public class InfoPriority {
public static void main(String[] args) throws InterruptedException {
MyThread it1 = new MyThread();
Thread p1 = new Thread(it1,"挨踢1");
MyThread it2 = new MyThread();
Thread p2 = new Thread(it2,"挨踢2");

p1.setPriority(Thread.MIN_PRIORITY);
p2.setPriority(Thread.MAX_PRIORITY);
p1.start();
p2.start();

Thread.sleep(100);
it1.stop();
it2.stop();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: