文档章节

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

刺猬一号
 刺猬一号
发布于 2017/06/12 19:46
字数 1507
阅读 8
收藏 0

一、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();
    }
}

© 著作权归作者所有

共有 人打赏支持
刺猬一号
粉丝 11
博文 373
码字总数 616361
作品 0
深圳
私信 提问
Java 多线程— 线程的生命周期及方法

这篇博客介绍线程的生命周期。 线程是一个动态执行的过程,它也有从创建到死亡的过程。 线程的几种状态 在 Thread 类中,有一个枚举内部类: 上面的信息以图片表示如下: 第一张图: 第二张图...

小刀爱编程
2018/11/03
0
0
学习笔记1:java多线程机制之线程概念

由于种种需求,今天开始由浅入深的学习java的多线程机制,而java语言的一大特性点就是内置对多线程的支持。 以下内容出自: http://blog.csdn.net/jiangwei0910410003/article/details/1996...

牧羊人Berg
2015/10/15
98
0
JAVA多线程--线程状态的转换

一、线程状态 线程状态总的可分为五大状态:分别是生、死、可运行、运行、等待/阻塞。 1、新状态:线程对象已经创建,还没有在其上调用start()方法。 2、可运行状态:当线程有资格运行,但调...

董家二少
2016/01/13
92
0
并发编程基础三--join线程,后台线程,线程睡眠,线程让步,改变线程优先级

Java的线程支持提供了很多便捷方法,如标题. 1.join线程 join线程的意思就是在当前这个线程A里,加入另一个线程B,此时A阻塞,进入就绪状态,等B完成(结束,线程死亡),A才会继续执行. 这个方法通常...

Zhao-Qian
2013/02/06
0
0
线程的生命周期和状态控制

一、线程的生命周期 线程状态转换图: 其中Thread.join()调用的是Object.wait()方法实现的,意思是让当前线程等待。是当前调用thread1.join()的线程等待,而不是让thread1这个线程等待。 1、...

小菜鸡1
2016/08/05
237
0

没有更多内容

加载失败,请刷新页面

加载更多

Scala学习(一)

学习Spark之前需要学习Scala。 参考学习的书籍:快学Scala

柠檬果过
26分钟前
1
0
了解Nginx

1. 安装Nginx 版本 nginx-1.14.0 如果想学习Java工程化、高性能及分布式、深入浅出。微服务、Spring,MyBatis,Netty源码分析的朋友可以加我的Java高级交流:854630135,群里有阿里大牛直播讲...

编程SHA
40分钟前
1
0
虚拟化 - KVM 和 Xen 比较

Linux虚拟化技术的用户目前有两种免费的开源管理程序可以选择:Xen和KVM。 作为较早出现的虚拟化技术,Xen是“第一类”运行在裸机上的虚拟化管理程序(Hypervisor),也是当前相当一部分商业...

临江仙卜算子
59分钟前
1
0
给windows server中的“未识别的网络”或“无法识别的网络”设置网络位置类型

在windows server中,如果网络没有被正确的识别,那么就需要手工设置一下网络位置类型。 将“公用网络”指定设置为“专用网络“ 【控制面板】--【系统和安全】--【管理工具】--【本地安全策略...

gugudu
今天
2
0
阿里强制要求的21条Java开发规范,可以避免很多坑

1. 【强制】避免通过一个类的对象引用访问此类的静态变量或静态方法,无谓增加编译器解析成本,直接用类名来访问即可。 2. 【强制】所有的覆写方法,必须加@Override注解。 说明:getObject...

天王盖地虎626
今天
13
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部