分享
 
 
 

Java Thread Programming 1.10 - Thread Groups

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

In Java, threads can be grouped together and associated with an instance of ThreadGroup. In this chapter, I’ll show you how to use some of the methods of ThreadGroup. At the end of the chapter, I’ll show you how to use the class ThreadViewer to visually display the status of all the threads running in the Java VM.

构造函数:

ThreadGroup groupB = new ThreadGroup(“groupB”);

ThreadGroup groupD = new ThreadGroup(groupC, “groupD”);//父线程组

getName()

To retrieve the name of a particular group, the getName() method is used.

String groupName = group.getName();

返回线程组名

Thread的构造函数

New Thread objects default to be in the same thread group as the thread that does the construction

Thread threadZ = new Thread(target);

新线程默认为在当前线程组中

If a new thread should be in another group, the desired thread group can be passed to the constructor for Thread.

Thread threadZ = new Thread(groupC, target);

也可以指定所属的线程组

getParent()

If you need to know which thread group a particular thread group belongs to, you can use the getParent() method on ThreadGroup.

ThreadGroup parentOfGroupD = groupD.getParent();

If getParent() is invoked on the root thread group, null is returned. In the VM, only one instance of ThreadGroup does not have a parent group, and that is the root group.

获得线程组的父线程组,如果根线程组调用此方法返回null。Java虚拟机中只有一个根线程。

activeGroupCount()/enumerate(ThreadGroup[])

The activeGroupCount() method returns the number of active thread groups in a particular ThreadGroup and all of its subgroups. Keep in mind that this can be dynamically changing, but it’s an accurate snapshot at a moment in time.

返回调用线程组及其子线程组中所有活动线程组数,只是某个时刻的值。

To get a reference to all of the groups and subgroups of a ThreadGroup, the enumerate(ThreadGroup[]) method can be used. If you don’t want to include a recursive search of the subgroups, use enumerate(ThreadGroup[], false) instead. Both methods return the number of groups copied into the array that is passed. If the array is not big enough, the extra groups are silently ignored. To get an idea of how big the destination array needs to be, you can use the value returned from activeGroupCount(). This code tries to capture all of the groups and subgroups of group:

enumerate(ThreadGroup[])

返回此线程组中所有线程组,包括子线程组中的线程组

enumerate(ThreadGroup[], false)

返回此线程组中所有线程组,不包括子线程组中的线程组

两个方法将线程组通过参数返回,如果参数中给的线程组不够大,则忽略余下的,所以,应该尽量大。

下面这端代码返回线程组中的所有线程组数组,真实大小

ThreadGroup group = // ...

int estimatedSize = 2 * group.activeGroupCount();

ThreadGroup[] dest = new ThreadGroup[estimatedSize];

int actualSize = group.enumerate(dest);

The count returned from activeGroupCount() is doubled in an attempt to be sure that the destination array is large enough. Based on estimatedSize, a destination array for the groups is allocated and referred to by dest. The enumerate(ThreadGroup[]) method copies up to dest.length groups into dest. The number of groups copied is returned and stored in actualSize. If actualSize is equal to dest.length, there is a good chance that dest was not big enough. Generally, actualSize is less than dest.length and indicates the number of valid groups in dest.

getThreadGroup()

If you need to know which thread group a thread belongs to, you can use the getThreadGroup() method on Thread.

ThreadGroup groupForThreadX = threadX.getThreadGroup();

groupForThreadX is a reference to the ThreadGroup that threadX belongs to. If a thread is no longer alive, getThreadGroup() returns null instead of a ThreadGroup.

To determine which thread group the thread executing a block of code belongs to, use:

ThreadGroup group = Thread.currentThread().getThreadGroup();

activeCount()

The activeCount() method returns the number of active threads in a particular ThreadGroup and all of its subgroups. Keep in mind that this can be dynamically changing, as new threads might be created and existing threads might be dying.

To get a reference to all of the threads in a ThreadGroup and all of its subgroups, the enumerate(Thread[]) method can be used. If you don’t want to include a recursive search of the subgroups, use enumerate(Thread[], false) instead. Both methods return the number of threads copied into the passed array. If the array is not big enough, the extra threads are silently ignored. To get an idea of how big the destination array needs to be, you can use the value returned from activeCount(). This code tries to capture all of the threads in group and its subgroups:

ThreadGroup group = // ...

int estimatedSize = 2 * group.activeCount();

Thread[] dest = new Thread[estimatedSize];

int actualSize = group.enumerate(dest);

同上,返回线程组中所有线程。

checkAccess()

The checkAccess() method of ThreadGroup is called internally by many of the other ThreadGroup methods. It checks to see if a SecurityManager exists for a VM. By default, applications do not have a SecurityManager installed. Applets, on the other hand, might ave one.

If a SecurityManager exists and it determines that a particular thread is not permitted to take an action, it throws a SecurityException. SecurityException is a subclass of RuntimeException, so try/catch blocks are typically not used. If no SecurityManager is installed, or if the SecurityManager approves of the access, checkAccess() silently returns.

检查虚拟机中是否包括SecurityManager,一般都没有,像Applet,可能会存在。如果有,且某个线程不允许访问,此方法会抛出SecurityException异常,如果没有,或者允许访问,则直接返回。

setMaxPriority() / getMaxPriority()

The setMaxPriority() method sets the maximum priority that all threads in a particular thread group and all of its subgroups can have. Threads that are already running at a higher priority are not affected. This method has an effect when new threads are constructed or when the setPriority() method of Thread is invoked.

If setPriority() is called with a priority higher than the maximum allowed for the group that a thread is in, the priority is silently lowered to the maximum allowed. The getMaxPriority() method returns the current maximum priority permitted for threads in a particular thread group.

设置线程组中所有线程(包括子线程组中的线程)的最大优先级。不影响现有的更高优先级的线程,新建线程setPriority更高的优先级时会有影响,会直接将其优先级降为线程组的最大优先级。

interrupt()

The interrupt() method of ThreadGroup can be used to signal an interrupt to all the threads in the group and subgroups. This method can be useful if several threads have been spawned to handle a task, and it’s time to signal all of them to shut down. (See Chapter 5, “Gracefully Stopping Threads,” for more on signaling threads to die by interrupting them.)

线程组的interrupt()会中止此线程组中的所有线程。

Deprecated -- stop(), suspend(),resume()

Class ThreadViewer

The class ThreadViewer (see Listing 10.1) graphically displays all of the threads currently running in the Java VM. It automatically refreshes itself every 5 seconds to keep current. ThreadViewer can be a handy tool to have around during the development and debugging of multithreaded applications.

用图表显示当前java虚拟机种的所有线程及其状态。5秒钟刷新一次保持更新。

ThreadViewerTableModel.java

/*

* Created on 2005-7-18

*

* Java Thread Programming - Paul Hyde

* Copyright ? 1999 Sams Publishing

* Jonathan Q. Bo 学习笔记

*

*/

package org.tju.msnrl.jonathan.thread.chapter9;

import java.awt.*;

import java.lang.reflect.*;

import javax.swing.*;

import javax.swing.table.*;

/**

* @author Jonathan Q. Bo from TJU MSNRL

*

* Email:jonathan.q.bo@gmail.com

* Blog:blog.csdn.net/jonathan_q_bo

* blog.yesky.net/jonathanundersun

*

* Enjoy Life with Sun!

*

*/

public class ThreadViewerTableModel extends AbstractTableModel {

private Object dataLock;

private int rowCount;

private Object[][] cellData;

private Object[][] pendingCellData;

/*列信息*/

private final int columnCount;

private final String[] columnName;

private final Class[] columnClass;

/*自运行对象及控制变量*/

private Thread internalThread;

private volatile boolean noStopRequested;

/*构造函数*/

public ThreadViewerTableModel(){

rowCount = 0;

cellData = new Object[0][0];

String[] names = {"Priority","Alive","Daemon","Interrupted","ThreadGroup","Thread Name"};

columnName = names;

Class[] classes = {

Integer.class,Boolean.class,

Boolean.class,Boolean.class,

String.class,String.class};

columnClass = classes;

columnCount = columnName.length;

/*控制并发访问*/

dataLock = new Object();

noStopRequested = true;

Runnable r = new Runnable(){

public void run(){

try{

runWork();

}catch(Exception e){

e.printStackTrace();

}

}

};

internalThread = new Thread(r,"ThreadViewer");

internalThread.setPriority(Thread.MAX_PRIORITY - 2);

internalThread.setDaemon(true);//守护线程,随着main线程结束而结束

internalThread.start();

}

private void runWork(){

Runnable transferPending = new Runnable(){

public void run(){

transferPendingCellData();

/*AbstractTableModel类的方法,更新table*/

fireTableDataChanged();

}

};

while(noStopRequested){

try{

createPendingCellData();

SwingUtilities.invokeAndWait(transferPending);

Thread.sleep(5000);

}catch(InvocationTargetException e1){

e1.printStackTrace();

stopRequest();

}catch(InterruptedException e2){

Thread.currentThread().interrupt();

}

}

}

private void createPendingCellData(){

Thread[] thread = findAllThreads();

Object[][] cell = new Object[thread.length][columnCount];

for(int i = 0; i < thread.length; i++){

Thread t = thread[i];

Object[] rowCell = cell[i];

rowCell[0] = new Integer(t.getPriority());

rowCell[1] = new Boolean(t.isAlive());

rowCell[2] = new Boolean(t.isDaemon());

rowCell[3] = new Boolean(t.isInterrupted());

rowCell[4] = t.getThreadGroup().getName();

rowCell[5] = t.getName();

}

synchronized(dataLock){

pendingCellData = cell;

}

}

private static Thread[] findAllThreads(){

ThreadGroup group = Thread.currentThread().getThreadGroup();

ThreadGroup topGroup = group;

/*循环获得根线程组*/

while(group != null){

topGroup = group;

group = group.getParent();

}

int estimatedSize = topGroup.activeCount() * 2;

Thread[] slackList = new Thread[estimatedSize];

int actualSize = topGroup.enumerate(slackList);

/*铐到实际大小尺寸的list*/

Thread[] list = new Thread[actualSize];

System.arraycopy(slackList,0,list,0,actualSize);

return list;

}

private void transferPendingCellData(){

synchronized(dataLock){

cellData = pendingCellData;

rowCount = cellData.length;

}

}

public void stopRequest(){

noStopRequested = false;

internalThread.interrupt();

}

public boolean isAlive(){

return internalThread.isAlive();

}

/* (non-Javadoc)

* @see javax.swing.table.TableModel#getColumnCount()

*/

public int getColumnCount() {

// TODO Auto-generated method stub

return columnCount;

}

/* (non-Javadoc)

* @see javax.swing.table.TableModel#getRowCount()

*/

public int getRowCount() {

// TODO Auto-generated method stub

return rowCount;

}

/* (non-Javadoc)

* @see javax.swing.table.TableModel#getValueAt(int, int)

*/

public Object getValueAt(int rowIndex, int columnIndex) {

// TODO Auto-generated method stub

return cellData[rowIndex][columnIndex];

}

public Class getColumnClass(int columnIndex){

return columnClass[columnIndex];

}

public String getColumnName(int columnIndex){

return columnName[columnIndex];

}

}

ThreadViewer.java

/*

* Created on 2005-7-18

*

* Java Thread Programming - Paul Hyde

* Copyright ? 1999 Sams Publishing

* Jonathan Q. Bo 学习笔记

*

*/

package org.tju.msnrl.jonathan.thread.chapter9;

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

import javax.swing.table.*;

/**

* @author Jonathan Q. Bo from TJU MSNRL

*

* Email:jonathan.q.bo@gmail.com

* Blog:blog.csdn.net/jonathan_q_bo

* blog.yesky.net/jonathanundersun

*

* Enjoy Life with Sun!

*

*/

public class ThreadViewer extends JPanel{

private ThreadViewerTableModel tableModel;

public ThreadViewer(){

tableModel = new ThreadViewerTableModel();

JTable table = new JTable(tableModel);

table.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);

TableColumnModel colModel = table.getColumnModel();

int numColumns = colModel.getColumnCount();

/*设置列宽*/

for(int i = 0; i < numColumns - 1; i++){

TableColumn col = colModel.getColumn(i);

col.sizeWidthToFit();

col.setPreferredWidth(col.getWidth() + 5);

col.setMaxWidth(col.getWidth() + 5);

}

JScrollPane sp = new JScrollPane(table);

setLayout(new BorderLayout());

add(sp,BorderLayout.CENTER);

}

public static JFrame createFramedInstance(){

final ThreadViewer viewer = new ThreadViewer();

final JFrame f = new JFrame("Thread Viewer");

f.addWindowListener(

new WindowAdapter(){

public void windowClosing(WindowEvent e){

System.out.println("windowclosing ... ");

f.setVisible(false);

f.dispose();

viewer.dispose();

}

}

);

f.setContentPane(viewer);

f.setSize(500,300);

f.setVisible(true);

return f;

}

public void dispose(){

tableModel.stopRequest();

}

protected void finalize() throws Throwable{

dispose();

}

public static void main(String[] args){

JFrame f = ThreadViewer.createFramedInstance();

f.addWindowListener(

new WindowAdapter(){

public void windowClosing(WindowEvent e){

System.out.println("system.exit(0)");

System.exit(0);

}

}

);

Object lock = new Object();

synchronized(lock){

try{

lock.wait();

}catch(InterruptedException x){

}

}

}

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有