java 线程 控制_Java线程个数简单控制

系统在运行时,有时候我们要控制它同时允许多少个线程运行,如果太多可能引起内存溢出之类的异常,所以在线程比较多的情况下我们可以控制它的最大线程数,这样系统可以在一种比较稳定的状态下运行。下面是一个简单实现,可以少加修改用在系统中去。

package thread;

public class CreateThread {

public static void main(String[] args) throws InterruptedException {

//比如我们现要创建30个子线程,但允许最大线程数为10

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

// 获取锁资源

synchronized (SubThread.class) {

int tCount = SubThread.getThreadCounts();

// 如果入库线程达到了最大允许的线程数

while (tCount >= 10) {

System.out.println("系统当前线程数为:" + tCount

+ ",已达到最大线程数 10,请等待其他线程执行完毕并释放系统资源");

// 释放锁,等待“线程数”资源,等待其他入库线程执行完毕

SubThread.class.wait();

/*

* 带条件的wait()(即放在条件语句执行的wait()方法),一定要放在while

* 条件里执行,因为被唤醒之后该线程有可能不会马上执行,只是把当前线程从等

* 待池中放入对象锁池队列中,直到获取到锁后才开始运行。所以在同步块里wait方

* 法前后的代码块不是原子性的,会分开执行,但sleep()不同,睡时不会释放锁。

* 所以等到执行时,可能条件已被其他的线程给改变了(像这里的最大线程数),此

* 时就需要再此判断该条件,否则条件可能不成立了

*/

tCount = SubThread.getThreadCounts();

}

// 重新启动一个子线程

Thread td = new SubThread();

td.start();

System.out.println("已创建新的子线程: " + td.getName());

}

}

}

}

package thread;

public class SubThread extends Thread {

// 线程计数器

static private int threadCounts;

// 线程名称池

static private String threadNames[];

static {

// 假设这里允许系统同时运行最大线程数为10个

int maxThreadCounts = 10;

threadNames = new String[maxThreadCounts];

// 初始化线程名称池

for (int i = 1; i <= maxThreadCounts; i++) {

threadNames[i - 1] = "子线程_" + i;

}

}

public SubThread() {

// 临界资源锁定

synchronized (SubThread.class) {

// 线程总数加1

threadCounts++;

// 从线程名称池中取出一个未使用的线程名

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

if (threadNames[i] != null) {

String temp = threadNames[i];

// 名被占用后清空

threadNames[i] = null;

// 初始化线程名称

this.setName(temp);

break;

}

}

}

}

public void run() {

System.out.println("-->>" + this.getName() + "开始运行");

try {

//模拟程序耗时

Thread.sleep(1000);

// ...

} catch (Exception e) {

System.out.println(e);

} finally {

synchronized (SubThread.class) {

// 线程运行完毕后减1

threadCounts--;

// 释放线程名称

String[] threadName = this.getName().split("_");

// 线程名使用完后放入名称池

threadNames[Integer.parseInt(threadName[1]) - 1] = this.getName();

/*

* 通知其他被阻塞的线程,但如果其他线程要执行,则该同步块一定要运行结束(即直

* 到释放占的锁),其他线程才有机会执行,所以这里的只是唤醒在此对象监视器上等待

* 的所有线程,让他们从等待池中进入对象锁池队列中,而这些线程重新运行时它们一定

* 要先要得该锁后才可能执行,这里的notifyAll是不会释放锁的,试着把下面的睡眠语

* 句注释去掉,即使你已调用了notify方法,发现CreateThread中的同步块还是好

* 像一直处于对象等待状态,其实调用notify方法后,CreateThread线程进入了对象锁

* 池队列中了,只要它一获取到锁,CreateThread所在线程就会真真的被唤醒并运行。

*/

SubThread.class.notifyAll();

//try {

//Thread.sleep(10000);

//} catch (InterruptedException e) {

//e.printStackTrace();

//}

System.out.println("----" + this.getName() + " 所占用资源释放完毕,当前系统正在运行的子线程数:"

+ threadCounts);

}

System.out.println("<

}

}

static public int getThreadCounts() {

synchronized (SubThread.class) {

return threadCounts;

}

}

}

某次运行结果:

已创建新的子线程: 子线程_1

已创建新的子线程: 子线程_2

已创建新的子线程: 子线程_3

-->>子线程_2开始运行

已创建新的子线程: 子线程_4

-->>子线程_4开始运行

已创建新的子线程: 子线程_5

已创建新的子线程: 子线程_6

-->>子线程_6开始运行

已创建新的子线程: 子线程_7

已创建新的子线程: 子线程_8

已创建新的子线程: 子线程_9

已创建新的子线程: 子线程_10

系统当前线程数为:10,已达到最大线程数 10,请等待其他线程执行完毕并释放系统资源

-->>子线程_1开始运行

-->>子线程_8开始运行

-->>子线程_10开始运行

-->>子线程_3开始运行

-->>子线程_5开始运行

-->>子线程_7开始运行

-->>子线程_9开始运行

----子线程_2 所占用资源释放完毕,当前系统正在运行的子线程数:9

已创建新的子线程: 子线程_2

系统当前线程数为:10,已达到最大线程数 10,请等待其他线程执行完毕并释放系统资源

<

-->>子线程_2开始运行

----子线程_4 所占用资源释放完毕,当前系统正在运行的子线程数:9

<

已创建新的子线程: 子线程_4

系统当前线程数为:10,已达到最大线程数 10,请等待其他线程执行完毕并释放系统资源

-->>子线程_4开始运行

----子线程_6 所占用资源释放完毕,当前系统正在运行的子线程数:9

<

----子线程_10 所占用资源释放完毕,当前系统正在运行的子线程数:8

<

----子线程_8 所占用资源释放完毕,当前系统正在运行的子线程数:7

<

已创建新的子线程: 子线程_6

已创建新的子线程: 子线程_8

已创建新的子线程: 子线程_10

系统当前线程数为:10,已达到最大线程数 10,请等待其他线程执行完毕并释放系统资源

----子线程_1 所占用资源释放完毕,当前系统正在运行的子线程数:9

<

-->>子线程_6开始运行

-->>子线程_10开始运行

已创建新的子线程: 子线程_1

----子线程_7 所占用资源释放完毕,当前系统正在运行的子线程数:9

<

----子线程_9 所占用资源释放完毕,当前系统正在运行的子线程数:8

<

-->>子线程_8开始运行

-->>子线程_1开始运行

----子线程_5 所占用资源释放完毕,当前系统正在运行的子线程数:7

<

----子线程_3 所占用资源释放完毕,当前系统正在运行的子线程数:6

<

已创建新的子线程: 子线程_3

已创建新的子线程: 子线程_5

-->>子线程_5开始运行

已创建新的子线程: 子线程_7

已创建新的子线程: 子线程_9

系统当前线程数为:10,已达到最大线程数 10,请等待其他线程执行完毕并释放系统资源

-->>子线程_9开始运行

-->>子线程_3开始运行

-->>子线程_7开始运行

----子线程_4 所占用资源释放完毕,当前系统正在运行的子线程数:9

<

----子线程_8 所占用资源释放完毕,当前系统正在运行的子线程数:8

<

----子线程_1 所占用资源释放完毕,当前系统正在运行的子线程数:7

<

已创建新的子线程: 子线程_1

已创建新的子线程: 子线程_4

-->>子线程_4开始运行

已创建新的子线程: 子线程_8

-->>子线程_1开始运行

-->>子线程_8开始运行

----子线程_5 所占用资源释放完毕,当前系统正在运行的子线程数:9

<

已创建新的子线程: 子线程_5

----子线程_2 所占用资源释放完毕,当前系统正在运行的子线程数:9

<

----子线程_6 所占用资源释放完毕,当前系统正在运行的子线程数:8

<

-->>子线程_5开始运行

----子线程_10 所占用资源释放完毕,当前系统正在运行的子线程数:7

<

----子线程_9 所占用资源释放完毕,当前系统正在运行的子线程数:6

<

已创建新的子线程: 子线程_2

已创建新的子线程: 子线程_6

已创建新的子线程: 子线程_9

已创建新的子线程: 子线程_10

系统当前线程数为:10,已达到最大线程数 10,请等待其他线程执行完毕并释放系统资源

-->>子线程_6开始运行

-->>子线程_10开始运行

----子线程_3 所占用资源释放完毕,当前系统正在运行的子线程数:9

已创建新的子线程: 子线程_3

系统当前线程数为:10,已达到最大线程数 10,请等待其他线程执行完毕并释放系统资源

<

----子线程_7 所占用资源释放完毕,当前系统正在运行的子线程数:9

已创建新的子线程: 子线程_7

<

-->>子线程_2开始运行

-->>子线程_9开始运行

-->>子线程_7开始运行

-->>子线程_3开始运行

----子线程_4 所占用资源释放完毕,当前系统正在运行的子线程数:9

<

----子线程_1 所占用资源释放完毕,当前系统正在运行的子线程数:8

<

----子线程_8 所占用资源释放完毕,当前系统正在运行的子线程数:7

<

----子线程_5 所占用资源释放完毕,当前系统正在运行的子线程数:6

<

----子线程_6 所占用资源释放完毕,当前系统正在运行的子线程数:5

<

----子线程_10 所占用资源释放完毕,当前系统正在运行的子线程数:4

<

----子线程_2 所占用资源释放完毕,当前系统正在运行的子线程数:3

<

----子线程_7 所占用资源释放完毕,当前系统正在运行的子线程数:2

<

----子线程_9 所占用资源释放完毕,当前系统正在运行的子线程数:1

<

----子线程_3 所占用资源释放完毕,当前系统正在运行的子线程数:0

<

分享到:

18e900b8666ce6f233d25ec02f95ee59.png

72dd548719f0ace4d5f9bca64e1d7715.png

2009-11-27 21:21

浏览 8845

评论


版权声明:本文为weixin_42513546原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。