首页 文章 精选 留言 我的

精选列表

搜索[并发],共10006篇文章
优秀的个人博客,低调大师

Java并发编程之ThreadGroup

ThreadGroup是Java提供的一种对线程进行分组管理的手段,可以对所有线程以组为单位进行操作,如设置优先级、守护线程等。 线程组也有父子的概念,如下图: 线程组的创建 1 public class ThreadGroupCreator { 2 3 public static void main(String[] args) { 4 //获取当前线程的group 5 ThreadGroup currentGroup = Thread.currentThread().getThreadGroup(); 6 //在当前线程执行流中新建一个Group1 7 ThreadGroup group1 = new ThreadGroup("Group1"); 8 //Group1的父线程,就是main线程所在Group 9 System.out.println(group1.getParent() == currentGroup); 10 //定义Group2, 指定group1为其父线程 11 ThreadGroup group2 = new ThreadGroup(group1, "Group2"); 12 System.out.println(group2.getParent() == group1); 13 } 14 } 线程组的基本操作 注意:后添加进线程组的线程,其优先级不能大于线程组的优先级 1 public class ThreadGroupBasic { 2 3 public static void main(String[] args) throws InterruptedException { 4 5 ThreadGroup group = new ThreadGroup("group1"); 6 Thread thread = new Thread(group, () -> { 7 while(true) { 8 try { 9 TimeUnit.SECONDS.sleep(1); 10 } catch (InterruptedException e) { 11 e.printStackTrace(); 12 } 13 } 14 }, "thread"); 15 thread.setDaemon(true); 16 thread.start(); 17 18 TimeUnit.MILLISECONDS.sleep(1); 19 20 ThreadGroup mainGroup = Thread.currentThread().getThreadGroup(); 21 //递归获取mainGroup中活跃线程的估计值 22 System.out.println("activeCount = " + mainGroup.activeCount()); 23 //递归获mainGroup中的活跃子group 24 System.out.println("activeGroupCount = " + mainGroup.activeGroupCount()); 25 //获取group的优先级, 默认为10 26 System.out.println("getMaxPriority = " + mainGroup.getMaxPriority()); 27 //获取group的名字 28 System.out.println("getName = " + mainGroup.getName()); 29 //获取group的父group, 如不存在则返回null 30 System.out.println("getParent = " + mainGroup.getParent()); 31 //活跃线程信息全部输出到控制台 32 mainGroup.list(); 33 System.out.println("----------------------------"); 34 //判断当前group是不是给定group的父线程, 如果两者一样,也会返回true 35 System.out.println("parentOf = " + mainGroup.parentOf(group)); 36 System.out.println("parentOf = " + mainGroup.parentOf(mainGroup)); 37 38 } 39 40 } 线程组的Interrupt 1 ublic class ThreadGroupInterrupt { 2 3 public static void main(String[] args) throws InterruptedException { 4 ThreadGroup group = new ThreadGroup("TestGroup"); 5 new Thread(group, () -> { 6 while(true) { 7 try { 8 TimeUnit.MILLISECONDS.sleep(2); 9 } catch (InterruptedException e) { 10 //received interrupt signal and clear quickly 11 System.out.println(Thread.currentThread().isInterrupted()); 12 break; 13 } 14 } 15 System.out.println("t1 will exit"); 16 }, "t1").start(); 17 new Thread(group, () -> { 18 while(true) { 19 try { 20 TimeUnit.MILLISECONDS.sleep(2); 21 } catch (InterruptedException e) { 22 //received interrupt signal and clear quickly 23 System.out.println(Thread.currentThread().isInterrupted()); 24 break; 25 } 26 } 27 System.out.println("t2 will exit"); 28 }, "t2").start(); 29 //make sure all threads start 30 TimeUnit.MILLISECONDS.sleep(2); 31 32 group.interrupt(); 33 } 34 35 } 线程组的destroy 1 public class ThreadGroupDestroy { 2 3 public static void main(String[] args) { 4 ThreadGroup group = new ThreadGroup("TestGroup"); 5 ThreadGroup mainGroup = Thread.currentThread().getThreadGroup(); 6 //before destroy 7 System.out.println("group.isDestroyed=" + group.isDestroyed()); 8 mainGroup.list(); 9 10 group.destroy(); 11 //after destroy 12 System.out.println("group.isDestroyed=" + group.isDestroyed()); 13 mainGroup.list(); 14 } 15 16 } 线程组设置守护线程组 线程组设置为守护线程组,并不会影响其线程是否为守护线程,仅仅表示当它内部没有active的线程的时候,会自动destroy 1 public class ThreadGroupDaemon { 2 3 public static void main(String[] args) throws InterruptedException { 4 ThreadGroup group1 = new ThreadGroup("group1"); 5 new Thread(group1, () -> { 6 try { 7 TimeUnit.SECONDS.sleep(1); 8 } catch (InterruptedException e) { 9 e.printStackTrace(); 10 } 11 }, "group1-thread1").start(); 12 ThreadGroup group2 = new ThreadGroup("group2"); 13 new Thread(group2, () -> { 14 try { 15 TimeUnit.SECONDS.sleep(1); 16 } catch (InterruptedException e) { 17 e.printStackTrace(); 18 } 19 }, "group1-thread2").start(); 20 group2.setDaemon(true); 21 22 TimeUnit.SECONDS.sleep(3); 23 System.out.println(group1.isDestroyed()); 24 System.out.println(group2.isDestroyed()); 25 } 26 }

优秀的个人博客,低调大师

Java并发编程-重入锁

章节目录 什么是重入锁 底层实现-如何实现重入 公平与非公平获取锁的区别与底层实现 1.什么是重入锁 1.1 重入锁的定义 重入锁ReentrantLock,支持重入的锁,表示一个线程对资源的重复加锁。 1.2 重入锁的特性 1.重进入 2.非/公平性获取锁 1.3 自定义同步器Mutex 的缺陷 当线程调用Mutex的lock()方法获取锁之后,再次调用lock()方法,该线程将会被 自己阻塞,原因是Mutex在实现tryAcquire(int acquires)方法时没有考虑占有锁 的线程再次获取锁的场景。 1.4 ReentrantLock & synchronized 关键字 1.synchronized 关键字支持隐式的重进入 2.ReentrantLock 在调用lock() 方法时,已经获取到锁的线程,能够再次调用 lock()方法获取到锁而不被阻塞,即可支持重入 1.4 公平性获取锁 公平性 含义 公平性获取锁 在绝对时间上,先对锁进行获取请求的请求一定先被满足,那么这个锁就是公平的 非公平性获取锁 无上述限制 事实上 公平锁机制往往没有非公平性机制获取锁的效率高,因为会牵扯到频繁的上下文切换,但公平锁可以减少饥饿发生的概率,等待越久的请求越能得到优先满足。 2. 底层实现-如何实现重入 重进入是指任意线程在获取到锁之后能够再次获取该锁,而不被阻塞,改特性实现需要解决以下两个问题: 线程再次获取锁 线程再次获取锁。锁需要去识别获取锁的线程是否为当前占据锁的线程,如果是,则再次成功获取。 锁的最终释放 线程重复n次获取了锁,随后在第n次释放锁,锁的释放要求锁对于被获取递 增的次数进行递减操作,当计数==0时表示锁已经成功释放。 2.1 可重入锁的源码非公平性获取同步状态(锁)的 nonfairTryAcquire() 方法 final boolean nonfairTryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { if (compareAndSetState(0, acquires)) { setExclusiveOwnerThread(current); return true; } } else if (current == getExclusiveOwnerThread()) { int nextc = c + acquires; if (nextc < 0) // overflow throw new Error("Maximum lock count exceeded"); setState(nextc); return true; } return false; } 该方法增加了再次获取同步状态的处理逻辑:通过判断当前线程是否为获取锁的线程来决定获取操作是否成功,如果是获取锁的线程的再次请求 则将同步状态值计数器进行递增并返回true,表示获取同步状态成功。 释放同步状态(锁) protected final boolean tryRelease(int releases) { int c = getState() - releases; if (Thread.currentThread() != getExclusiveOwnerThread()) throw new IllegalMonitorStateException(); boolean free = false; if (c == 0) { free = true; setExclusiveOwnerThread(null); } setState(c); return free; } 如果该锁被获取了n次,那么前n-1此tryRelease(int release) 方法必须返回false,而只有同步状态完全释放了,才能返回true。 3.公平与非公平获取锁的区别与底层实现 3.1 公平性获取锁的底层实现 公平性获取锁即按照客观时间顺序,FIFO方式获取同步状态 具体源码如下所示 protected final boolean tryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { if (!hasQueuedPredecessors() && compareAndSetState(0, acquires)) { setExclusiveOwnerThread(current); return true; } } else if (current == getExclusiveOwnerThread()) { int nextc = c + acquires; if (nextc < 0) throw new Error("Maximum lock count exceeded"); setState(nextc); return true; } return false; } 公平性获取同步状态的与非公平性获取同步状态的区别在于hasQueuedPredecessors()方法的使用,即加入了当前节点是否有前驱节点的判断,如果该方法返回true,则表示有线程比当前线程更早的加入到同步队列(更早的请求获取锁),因此需要等待前驱线程获取并释放锁之后才能继续获取锁。 非公平性获取锁的实现 公平性获取锁保证了锁的获取顺序按照FIFO原则,不会出现线程“饥饿”的现象,但代价是进行大量的线程切换。 非公平性锁虽然可能造成线程饥饿,但是有极少的线程切换,保证了其更大的吞吐量。

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册