java多线程 --总结2

来源:互联网 发布:php header跳转404 编辑:程序博客网 时间:2024/06/05 19:12

本文转自:http://www.cnblogs.com/lwbqqyumidi/p/3817517.html

四.Java多线程的阻塞状态与线程控制

上文已经提到Java阻塞的几种具体类型。下面分别看下引起Java线程阻塞的主要方法。

1.join()

join —— 让一个线程等待另一个线程完成才继续执行。如A线程线程执行体中调用B线程的join()方法,则A线程被阻塞,知道B线程执行完为止,A才能得以继续执行。

public class ThreadTest {    public static void main(String[] args) {        MyRunnable myRunnable = new MyRunnable();        Thread thread = new Thread(myRunnable);        for (int i = 0; i < 100; i++) {            System.out.println(Thread.currentThread().getName() + " " + i);            if (i == 30) {                thread.start();                try {                    thread.join();    // main线程需要等待thread线程执行完后才能继续执行                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        }    }}class MyRunnable implements Runnable {    @Override    public void run() {        for (int i = 0; i < 100; i++) {            System.out.println(Thread.currentThread().getName() + " " + i);        }    }}

2.sleep()

sleep —— 让当前的正在执行的线程暂停指定的时间,并进入阻塞状态。在其睡眠的时间段内,该线程由于不是处于就绪状态,因此不会得到执行的机会。即使此时系统中没有任何其他可执行的线程,出于sleep()中的线程也不会执行。因此sleep()方法常用来暂停线程执行。

前面有讲到,当调用了新建的线程的start()方法后,线程进入到就绪状态,可能会在接下来的某个时间获取CPU时间片得以执行,如果希望这个新线程必然性的立即执行,直接调用原来线程的sleep(1)即可。

public class ThreadTest {    public static void main(String[] args) {        MyRunnable myRunnable = new MyRunnable();        Thread thread = new Thread(myRunnable);        for (int i = 0; i < 100; i++) {            System.out.println(Thread.currentThread().getName() + " " + i);            if (i == 30) {                thread.start();                try {                    Thread.sleep(1);   // 使得thread必然能够马上得以执行                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        }    }}class MyRunnable implements Runnable {    @Override    public void run() {        for (int i = 0; i < 100; i++) {            System.out.println(Thread.currentThread().getName() + " " + i);        }    }}

注:睡一个毫秒级够了,因为CPU不会空闲,会切换到新建的线程。

3.后台线程(Daemon Thread)

概念/目的:后台线程主要是为其他线程(相对可以称之为前台线程)提供服务,或“守护线程”。如JVM中的垃圾回收线程。

生命周期:后台线程的生命周期与前台线程生命周期有一定关联。主要体现在:当所有的前台线程都进入死亡状态时,后台线程会自动死亡(其实这个也很好理解,因为后台线程存在的目的在于为前台线程服务的,既然所有的前台线程都死亡了,那它自己还留着有什么用…伟大啊 ! !)。

设置后台线程:调用Thread对象的setDaemon(true)方法可以将指定的线程设置为后台线程。

public class ThreadTest {    public static void main(String[] args) {        Thread myThread = new MyThread();        for (int i = 0; i < 100; i++) {            System.out.println("main thread i = " + i);            if (i == 20) {                myThread.setDaemon(true);                myThread.start();            }        }    }}class MyThread extends Thread {    public void run() {        for (int i = 0; i < 100; i++) {            System.out.println("i = " + i);            try {                Thread.sleep(1);            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }    }}

判断线程是否是后台线程:调用thread对象的isDeamon()方法。

注:main线程默认是前台线程,前台线程创建中创建的子线程默认是前台线程,后台线程中创建的线程默认是后台线程。调用setDeamon(true)方法将前台线程设置为后台线程时,需要在start()方法调用之前。前天线程都死亡后,JVM通知后台线程死亡,但从接收指令到作出响应,需要一定的时间。

4.改变线程的优先级/setPriority():

每个线程在执行时都具有一定的优先级,优先级高的线程具有较多的执行机会。每个线程默认的优先级都与创建它的线程的优先级相同。main线程默认具有普通优先级。

设置线程优先级:setPriority(int priorityLevel)。参数priorityLevel范围在1-10之间,常用的有如下三个静态常量值:

MAX_PRIORITY:10

MIN_PRIORITY:1

NORM_PRIORITY:5

获取线程优先级:getPriority()。

注:具有较高线程优先级的线程对象仅表示此线程具有较多的执行机会,而非优先执行。

public class ThreadTest {    public static void main(String[] args) {        Thread myThread = new MyThread();        for (int i = 0; i < 100; i++) {            System.out.println("main thread i = " + i);            if (i == 20) {                myThread.setPriority(Thread.MAX_PRIORITY);                myThread.start();            }        }    }}class MyThread extends Thread {    public void run() {        for (int i = 0; i < 100; i++) {            System.out.println("i = " + i);        }    }}

5.线程让步:yield()

上一篇博文中已经讲到了yield()的基本作用,同时,yield()方法还与线程优先级有关,当某个线程调用yiled()方法从运行状态转换到就绪状态后,CPU从就绪状态线程队列中只会选择与该线程优先级相同或优先级更高的线程去执行。

public class ThreadTest {    public static void main(String[] args) {        Thread myThread1 = new MyThread1();        Thread myThread2 = new MyThread2();        myThread1.setPriority(Thread.MAX_PRIORITY);        myThread2.setPriority(Thread.MIN_PRIORITY);        for (int i = 0; i < 100; i++) {            System.out.println("main thread i = " + i);            if (i == 20) {                myThread1.start();                myThread2.start();                Thread.yield();            }        }    }}class MyThread1 extends Thread {    public void run() {        for (int i = 0; i < 100; i++) {            System.out.println("myThread 1 --  i = " + i);        }    }}class MyThread2 extends Thread {    public void run() {        for (int i = 0; i < 100; i++) {            System.out.println("myThread 2 --  i = " + i);        }    }}
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 服务类没有进项票怎么办 教师对学生缺乏耐心怎么办 买了竹料烂尾楼怎么办 刚毕业想换工作怎么办 客厅灯变不了光怎么办 塑料镀铝浸底漆咬底怎么办 标志408钥匙掉了怎么办 房本测绘页丢了怎么办 房本测绘页信息有误怎么办 税务登记证办完没有年检怎么办 建筑施工升降机司机证怎么办 北京建筑施工证怎么办呢 模拟城市5水抽干了怎么办 ip地址错误网络无法接通怎么办 rhino模型太大打开半天怎么办 日本新干线车票丢了怎么办 房间太干燥怎么办又热 薄荷叶子全干了怎么办 水培栀子花叶子蔫了怎么办 薄荷叶叶边干了怎么办 碗莲叶子发黑腐烂怎么办 龟背叶叶子蔫了怎么办 夏天龟背竹蔫了怎么办 春羽叶子长黄斑怎么办 百合竹叶子发黄掉落怎么办 凤尾蕨叶子蔫了怎么办 绿地珊瑚蕨干了怎么办 翠云草叶子蔫了怎么办 珊瑚蕨叶子烂了怎么办 黑骨茶叶子黑斑怎么办 外场主持没有人互动怎么办 企业年报填错了怎么办 手机忘了放哪了怎么办 燃气卡车没气了怎么办 老房子拆了重建怎么办 加了差的汽油怎么办 事业单位未满5年怎么办 小学孩子不会制订学习计划怎么办 忘记提交原创怎么办百度熊掌号 计算机一级报名表填错了怎么办 离婚了不给孩子生活费怎么办