Java线程:线程的调度-守护线程
 
守护线程与普通线程写法上基本么啥区别,调用线程对象的方法setDaemon(true),则可以将其设置为守护线程。
 
守护线程使用的情况较少,但并非无用,举例来说,JVM的垃圾回收、内存管理等线程都是守护线程。还有就是在做数据库应用时候,使用的数据库连接池,连接池本身也包含着很多后台线程,监控连接个数、超时时间、状态等等。
 
setDaemon方法的详细说明:
public final void setDaemon(boolean on)将该线程标记为守护线程或用户线程。当正在运行的线程都是守护线程时,Java
虚拟机退出。    

  该方法必须在启动线程前调用。    

  该方法首先调用该线程的 checkAccess 方法,且不带任何参数。这可能抛出 SecurityException(在当前线程中)。    

  参数: 

    on - 如果为 true,则将该线程标记为守护线程。    

  抛出:    

    IllegalThreadStateException - 如果该线程处于活动状态。    

    SecurityException - 如果当前线程无法修改该线程。 

  另请参见: 

    isDaemon(), checkAccess()


 
/** 

* Java线程:线程的调度-守护线程 



* @author leizhimin 2009-11-4 9:02:40 

*/ 
public class Test { 

        public static void main(String[] args) { 

                Thread t1 = new MyCommon(); 

                Thread t2 = new Thread(new MyDaemon()); 

                t2.setDaemon(true);        //设置为守护线程 

                t2.start(); 

                t1.start(); 

        } 



class MyCommon extends Thread { 

        public void run() { 

                for (int i = 0; i < 5; i++) { 

                        System.out.println("线程1第" + i + "次执行!"); 

                        try { 

                                Thread.sleep(7); 

                        } catch (InterruptedException e) { 

                                e.printStackTrace(); 

                        } 

                } 

        } 



class MyDaemon implements Runnable { 

        public void run() { 

                for (long i = 0; i < 9999999L; i++) { 

                        System.out.println("后台线程第" + i + "次执行!"); 

                        try { 

                                Thread.sleep(7); 

                        } catch (InterruptedException e) { 

                                e.printStackTrace(); 

                        } 

                } 

        } 

}
 
后台线程第0次执行! 

线程1第0次执行! 

线程1第1次执行! 

后台线程第1次执行! 

后台线程第2次执行! 

线程1第2次执行! 

线程1第3次执行! 

后台线程第3次执行! 

线程1第4次执行! 

后台线程第4次执行! 

后台线程第5次执行! 

后台线程第6次执行! 

后台线程第7次执行! 

Process finished with exit code 0
 
从上面的执行结果可以看出:
前台线程是保证执行完毕的,后台线程还没有执行完毕就退出了。
 
实际上:JRE判断程序是否执行结束的标准是所有的前台执线程行完毕了,而不管后台线程的状态,因此,在使用后台县城时候一定要注意这个问题。

本文出自 “熔 岩” 博客,请务必保留此出处http://lavasoft.blog.51cto.com/62575/221845

Java线程:线程的调度-合并
 
线程的合并的含义就是将几个并行线程的线程合并为一个单线程执行,应用场景是当一个线程必须等待另一个线程执行完毕才能执行时可以使用join方法。
 
join为非静态方法,定义如下:
void join()    

    等待该线程终止。    
void join(long millis)    

    等待该线程终止的时间最长为 millis 毫秒。    
void join(long millis, int nanos)    

    等待该线程终止的时间最长为 millis 毫秒 + nanos 纳秒。
 
/** 

* Java线程:线程的调度-合并 



* @author leizhimin 2009-11-4 9:02:40 

*/ 
public class Test { 

        public static void main(String[] args) { 

                Thread t1 = new MyThread1(); 

                t1.start(); 

                for (int i = 0; i < 20; i++) { 

                        System.out.println("主线程第" + i + "次执行!"); 

                        if (i > 2) try { 

                                //t1线程合并到主线程中,主线程停止执行过程,转而执行t1线程,直到t1执行完毕后继续。 

                                t1.join(); 

                        } catch (InterruptedException e) { 

                                e.printStackTrace(); 

                        } 

                } 

        } 



class MyThread1 extends Thread { 

        public void run() { 

                for (int i = 0; i < 10; i++) { 

                        System.out.println("线程1第" + i + "次执行!"); 

                } 

        } 

}
 
主线程第0次执行! 

主线程第1次执行! 

主线程第2次执行! 

线程1第0次执行! 

主线程第3次执行! 

线程1第1次执行! 

线程1第2次执行! 

线程1第3次执行! 

线程1第4次执行! 

线程1第5次执行! 

线程1第6次执行! 

线程1第7次执行! 

线程1第8次执行! 

线程1第9次执行! 

主线程第4次执行! 

主线程第5次执行! 

主线程第6次执行! 

主线程第7次执行! 

主线程第8次执行! 

主线程第9次执行! 

主线程第10次执行! 

主线程第11次执行! 

主线程第12次执行! 

主线程第13次执行! 

主线程第14次执行! 

主线程第15次执行! 

主线程第16次执行! 

主线程第17次执行! 

主线程第18次执行! 

主线程第19次执行! 

Process finished with exit code 0

本文出自 “熔 岩” 博客,请务必保留此出处http://lavasoft.blog.51cto.com/62575/221817

Java5中,添加了障碍器类,为了适应一种新的设计需求,比如一个大型的任务,常常需要分配好多子任务去执行,只有当所有子任务都执行完成时候,才能执行主任务,这时候,就可以选择障碍器了。
 
障碍器是多线程并发控制的一种手段,用法很简单。下面给个例子:
 
import java.util.concurrent.BrokenBarrierException; 
import java.util.concurrent.CyclicBarrier; 

/** 

* Java线程:新特征-障碍器 



* @author leizhimin 2009-11-6 10:50:10 

*/ 
public class Test { 

        public static void main(String[] args) { 

                //创建障碍器,并设置MainTask为所有定数量的线程都达到障碍点时候所要执行的任务(Runnable) 

                CyclicBarrier cb = new CyclicBarrier(7, new MainTask()); 

                new SubTask("A", cb).start(); 

                new SubTask("B", cb).start(); 

                new SubTask("C", cb).start(); 

                new SubTask("D", cb).start(); 

                new SubTask("E", cb).start(); 

                new SubTask("F", cb).start(); 

                new SubTask("G", cb).start(); 

        } 



/** 

* 主任务 

*/ 
class MainTask implements Runnable { 

        public void run() { 

                System.out.println(">>>>主任务执行了!<<<<"); 

        } 



/** 

* 子任务 

*/ 
class SubTask extends Thread { 

        private String name; 

        private CyclicBarrier cb; 

        SubTask(String name, CyclicBarrier cb) { 

                this.name = name; 

                this.cb = cb; 

        } 

        public void run() { 

                System.out.println("[子任务" + name + "]开始执行了!"); 

                for (int i = 0; i < 999999; i++) ;    //模拟耗时的任务 

                System.out.println("[子任务" + name + "]开始执行完成了,并通知障碍器已经完成!"); 

                try { 

                        //通知障碍器已经完成 

                        cb.await(); 

                } catch (InterruptedException e) { 

                        e.printStackTrace(); 

                } catch (BrokenBarrierException e) { 

                        e.printStackTrace(); 

                } 

        } 

}
 
运行结果:
[子任务E]开始执行了! 

[子任务E]开始执行完成了,并通知障碍器已经完成! 

[子任务F]开始执行了! 

[子任务G]开始执行了! 

[子任务F]开始执行完成了,并通知障碍器已经完成! 

[子任务G]开始执行完成了,并通知障碍器已经完成! 

[子任务C]开始执行了! 

[子任务B]开始执行了! 

[子任务C]开始执行完成了,并通知障碍器已经完成! 

[子任务D]开始执行了! 

[子任务A]开始执行了! 

[子任务D]开始执行完成了,并通知障碍器已经完成! 

[子任务B]开始执行完成了,并通知障碍器已经完成! 

[子任务A]开始执行完成了,并通知障碍器已经完成! 

>>>>主任务执行了!<<<< 

Process finished with exit code 0
 
从执行结果可以看出,所有子任务完成的时候,主任务执行了,达到了控制的目标。

本文出自 “熔 岩” 博客,请务必保留此出处http://lavasoft.blog.51cto.com/62575/222738

Java线程是Java语言中一个非常重要的部分,Java5之前,多线程的语言支持还是比较弱的,内容也较少,写一个复杂的多线程程序是相当有挑战性的。
 
在Java5以后,Java对多线程做了很多扩展,扩展部分称之为并发包。这部分内容大大增强了Java多线程编程的能力,通过使用Java5线程新特征的API,可以很容易的做出复杂的多线程程序。与其他语言相比,已经是相当强悍了。
 
通过十多篇博文,将Java多线程的方方面面过了一遍,对我来说是一个学习和提高的过程,也为Java线程系列博文能给后来的学习者带来便利。
 
知识点都过了一遍,要总结起来感觉很困难,毕竟Java线程是一个庞大的话题,不知道从何说起,如果泛泛而谈,那总结还有什么意义呢,再次,将前面的博文串联起来,按照先后顺序加上链接,以方便浏览也最好的首尾。
 
下面是Java线程系列博文的一个编目:
 

Java线程:新特征-锁(上)

Java线程:大总结

 
 
 
另外,在网上看到两篇不错的博文,可以参考参考:

本文出自 “熔 岩” 博客,请务必保留此出处http://lavasoft.blog.51cto.com/62575/222742

Java线程:线程的调度-守护线程——Java线程:线程的调度-合并——Java线程:新特征-障碍器——Java线程:大总结的更多相关文章

  1. 转:【Java并发编程】之二十二:并发新特性—障碍器CyclicBarrier(含代码)

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/17512983 CyclicBarrier(又叫障碍器)同样是Java5中加入的新特性,使用 ...

  2. 【Java并发编程】:并发新特性—障碍器CyclicBarrier

    CyclicBarrier(又叫障碍器)同样是Java5中加入的新特性,使用时需要导入Java.util.concurrent.CylicBarrier.它适用于这样一种情况:你希望创建一组任务,它们 ...

  3. Java线程新特征——Java并发库

    一.线程池   Sun在Java5中,对Java线程的类库做了大量的扩展,其中线程池就是Java5的新特征之一,除了线程池之外,还有很多多线程相关的内容,为多线程的编程带来了极大便利.为了编写高效稳定 ...

  4. (转)Java线程:新特征-原子量,障碍器

    Java线程:新特征-原子量   所谓的原子量即操作变量的操作是“原子的”,该操作不可再分,因此是线程安全的.   为何要使用原子变量呢,原因是多个线程对单个变量操作也会引起一些问题.在Java5之前 ...

  5. Java线程:新特征-线程池

    Sun在Java5中,对Java线程的类库做了大量的扩展,其中线程池就是Java5的新特征之一,除了线程池之外,还有很多多线程相关的内容,为多线程的编程带来了极大便利.为了编写高效稳定可靠的多线程程序 ...

  6. (转)Java线程:新特征-线程池

    Java线程:新特征-线程池   Sun在Java5中,对Java线程的类库做了大量的扩展,其中线程池就是Java5的新特征之一,除了线程池之外,还有很多多线程相关的内容,为多线程的编程带来了极大便利 ...

  7. Java多线程-新特征-阻塞栈LinkedBlockingDeque

    对于阻塞栈,与阻塞队列相似.不同点在于栈是“后入先出”的结构,每次操作的是栈顶,而队列是“先进先出”的结构,每次操作的是队列头. 这里要特别说明一点的是,阻塞栈是Java6的新特征.. Java为阻塞 ...

  8. Java多线程-线程的调度(守护线程)

    本文转自http://www.cnblogs.com/linjiqin/p/3210004.html 感谢作者 守护线程与普通线程写法上基本没啥区别,调用线程对象的方法setDaemon(true), ...

  9. Java多线程系列 基础篇03 线程的优先级和守护线程

    1. 线程优先级 现代操作系统中基本上使用时间分片的方式调度线程,通过设置线程优先级,使优先级高的线程获得时间片的次数多于优先级低的线程. 在java 线程中,通过一个整形变量prority来控制优先 ...

  10. JAVA并发实现四(守护线程和线程阻塞)

    守护线程     Java中有两类线程:User Thread(用户线程).Daemon Thread(守护线程) 用户线程即运行在前台的线程,而守护线程是运行在后台的线程. 守护线程作用是为其他前台 ...

随机推荐

  1. bacnet mstp设备数据 转IEC61850项目案例

    目录 1 案例说明 1 2 VFBOX网关工作原理 1 3 使用YABE软件读取BACNET MSTP设备信息 2 4 配置网关采集BACNET MSTP数据 4 5 用IEC61850协议转发数据 ...

  2. NDP 协议

    Ref: http://ipv6.infosws.cn/20201009/40639.html IPv6系列基础篇(下)--邻居发现协议NDP IPv6之基础协议(3)讲NDP 里面NS, NA 报文 ...

  3. 国内加速拉取docker镜像的几种方法

    参考首页 快捷命令,使用本站代理拉取镜像,并修改回原始镜像名,在删除代理镜像名. 参考以下 docker cli 和 docker-compose.yml 修改镜像名后,继续一直使用本站代理服务未启动 ...

  4. 使用VSCode搭建UniApp + TS + Vue3 + Vite项目

    uniapp是一个使用Vue.js开发所有前端应用的框架,开发者编写一套代码,可发布到iOS.Android.以及各种小程序.深受广大前端开发者的喜爱.uniapp官方也提供了自己的IDE工具HBui ...

  5. SpringMVC——SSM整合——项目异常处理

    项目异常处理 项目异常分类 业务异常 不规范的用户行为产生的异常    规范的用户行为产生的异常    系统异常 项目运行过程中可预计且无法避免的异常    其他异常 编程人员未预期到的异常    项 ...

  6. 简述 JavaScript脚本的执行原理?

    js 是一种动态 . 弱类型 . 基于原型的语言 ,通过浏览器可以直接执行: 当浏览器遇到 <script></script>标记时 , 会执行标记之间的js 代码:然后js ...

  7. Nuxt.js 应用中的 kit:compatibility 事件钩子详解

    title: Nuxt.js 应用中的 kit:compatibility 事件钩子详解 date: 2024/10/11 updated: 2024/10/11 author: cmdragon e ...

  8. NOI 2024

    Day1 T1 集合(set) 容易发现两个序列等价当且仅当,所有数字在序列中出现位置的集合构成集族相等. 考虑哈希,对于一个集合 \(S\),令它的哈希值为 \(f(S) = (\sum\limit ...

  9. 鸿蒙NEXT开发声明式UI是咋回事?

    大家好,我是 V 哥,ArkTS 是 HarmonyOS 优选的主力应用开发语言,它在 TypeScript 的基础上进行了扩展,提供了声明式 UI 描述.自定义组件和动态扩展 UI 元素的能力.这些 ...

  10. Stream流,集合与基本数组的相互转换

    Arrays类的Api stream()方法传入数组,返回对应的stream流. Collection集合的Api: stream()不传参数,返回Stream流. 有了上述Api可以完成如下转换.. ...