`

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("<<--" + this.getName() + "运行结束");
		}
	}

	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运行结束
-->>子线程_2开始运行
----子线程_4 所占用资源释放完毕,当前系统正在运行的子线程数:9
<<--子线程_4运行结束
已创建新的子线程: 子线程_4
系统当前线程数为:10,已达到最大线程数 10,请等待其他线程执行完毕并释放系统资源
-->>子线程_4开始运行
----子线程_6 所占用资源释放完毕,当前系统正在运行的子线程数:9
<<--子线程_6运行结束
----子线程_10 所占用资源释放完毕,当前系统正在运行的子线程数:8
<<--子线程_10运行结束
----子线程_8 所占用资源释放完毕,当前系统正在运行的子线程数:7
<<--子线程_8运行结束
已创建新的子线程: 子线程_6
已创建新的子线程: 子线程_8
已创建新的子线程: 子线程_10
系统当前线程数为:10,已达到最大线程数 10,请等待其他线程执行完毕并释放系统资源
----子线程_1 所占用资源释放完毕,当前系统正在运行的子线程数:9
<<--子线程_1运行结束
-->>子线程_6开始运行
-->>子线程_10开始运行
已创建新的子线程: 子线程_1
----子线程_7 所占用资源释放完毕,当前系统正在运行的子线程数:9
<<--子线程_7运行结束
----子线程_9 所占用资源释放完毕,当前系统正在运行的子线程数:8
<<--子线程_9运行结束
-->>子线程_8开始运行
-->>子线程_1开始运行
----子线程_5 所占用资源释放完毕,当前系统正在运行的子线程数:7
<<--子线程_5运行结束
----子线程_3 所占用资源释放完毕,当前系统正在运行的子线程数:6
<<--子线程_3运行结束
已创建新的子线程: 子线程_3
已创建新的子线程: 子线程_5
-->>子线程_5开始运行
已创建新的子线程: 子线程_7
已创建新的子线程: 子线程_9
系统当前线程数为:10,已达到最大线程数 10,请等待其他线程执行完毕并释放系统资源
-->>子线程_9开始运行
-->>子线程_3开始运行
-->>子线程_7开始运行
----子线程_4 所占用资源释放完毕,当前系统正在运行的子线程数:9
<<--子线程_4运行结束
----子线程_8 所占用资源释放完毕,当前系统正在运行的子线程数:8
<<--子线程_8运行结束
----子线程_1 所占用资源释放完毕,当前系统正在运行的子线程数:7
<<--子线程_1运行结束
已创建新的子线程: 子线程_1
已创建新的子线程: 子线程_4
-->>子线程_4开始运行
已创建新的子线程: 子线程_8
-->>子线程_1开始运行
-->>子线程_8开始运行
----子线程_5 所占用资源释放完毕,当前系统正在运行的子线程数:9
<<--子线程_5运行结束
已创建新的子线程: 子线程_5
----子线程_2 所占用资源释放完毕,当前系统正在运行的子线程数:9
<<--子线程_2运行结束
----子线程_6 所占用资源释放完毕,当前系统正在运行的子线程数:8
<<--子线程_6运行结束
-->>子线程_5开始运行
----子线程_10 所占用资源释放完毕,当前系统正在运行的子线程数:7
<<--子线程_10运行结束
----子线程_9 所占用资源释放完毕,当前系统正在运行的子线程数:6
<<--子线程_9运行结束
已创建新的子线程: 子线程_2
已创建新的子线程: 子线程_6
已创建新的子线程: 子线程_9
已创建新的子线程: 子线程_10
系统当前线程数为:10,已达到最大线程数 10,请等待其他线程执行完毕并释放系统资源
-->>子线程_6开始运行
-->>子线程_10开始运行
----子线程_3 所占用资源释放完毕,当前系统正在运行的子线程数:9
已创建新的子线程: 子线程_3
系统当前线程数为:10,已达到最大线程数 10,请等待其他线程执行完毕并释放系统资源
<<--子线程_3运行结束
----子线程_7 所占用资源释放完毕,当前系统正在运行的子线程数:9
已创建新的子线程: 子线程_7
<<--子线程_7运行结束
-->>子线程_2开始运行
-->>子线程_9开始运行
-->>子线程_7开始运行
-->>子线程_3开始运行
----子线程_4 所占用资源释放完毕,当前系统正在运行的子线程数:9
<<--子线程_4运行结束
----子线程_1 所占用资源释放完毕,当前系统正在运行的子线程数:8
<<--子线程_1运行结束
----子线程_8 所占用资源释放完毕,当前系统正在运行的子线程数:7
<<--子线程_8运行结束
----子线程_5 所占用资源释放完毕,当前系统正在运行的子线程数:6
<<--子线程_5运行结束
----子线程_6 所占用资源释放完毕,当前系统正在运行的子线程数:5
<<--子线程_6运行结束
----子线程_10 所占用资源释放完毕,当前系统正在运行的子线程数:4
<<--子线程_10运行结束
----子线程_2 所占用资源释放完毕,当前系统正在运行的子线程数:3
<<--子线程_2运行结束
----子线程_7 所占用资源释放完毕,当前系统正在运行的子线程数:2
<<--子线程_7运行结束
----子线程_9 所占用资源释放完毕,当前系统正在运行的子线程数:1
<<--子线程_9运行结束
----子线程_3 所占用资源释放完毕,当前系统正在运行的子线程数:0
<<--子线程_3运行结束

分享到:
评论

相关推荐

    java线程 线程学习资料 java线程教程

    java线程 线程 教程 java线程教程 java线程学习资料 本教程有什么内容? 本教程研究了线程的基础知识— 线程是什么、线程为什么有用以及怎么开始编写使用线程的简单 程序。 我们还将研究更复杂的、使用线程的应用...

    java线程初解

    本教程有什么内容? 本教程研究了线程的基础知识 — 线程是什么、线程为什么有用以及怎么开始编写使用...学习完本教程之后,您应该可以编写一个使用线程的简单程序。您还应该可以阅读并理解以简单方 法使用线程的程序。

    java线程

    程研究了线程的基础知识— 线程是什么、线程为什么有用以及怎么开始编写使用线程的简单 程序。 我们还将研究更复杂的、使用线程的应用程序的基本构件— 如何在线程之间交换数据、如何控制 线程以及线程如何互相通信...

    JAVA线程简介(多线程)

    本教程研究了线程的基础知识 — 线程是什么、线程为什么有用以及怎么开始编写使用线程的简单程序。 &lt;br&gt;我们还将研究更复杂的、使用线程的应用程序的基本构件 — 如何在线程之间交换数据、如何控制线程以及线程...

    Java线程教程(详解java线程使用) pdf.rar

    Java线程教程(详解java线程使用) pdf,主要研究了线程的基础知识线程是什么、线程为什么有用以及怎么开始编写使用线程的简单程序。还将研究更复杂的、使用线程的应用程序的基本构件——如何在线程之间交换数据、...

    线程+监听技术 简单的例子 和详细讲解

     所谓线程(或称线索,thread),指程序中的以单一的顺序控制流。线程按顺序执行,即在一个线程中,一个时刻只能由一个执行点。显然,按传统方法设计的程序,无论是单道执行的程序,还是由多个进程并发执行的多道...

    java线程学习

    本教程有什么内容? 本教程研究了线程的基础知识 — 线程是什么、线程为什么有用以及怎么开始编写使用...学习完本教程之后,您应该可以编写一个使用线程的简单程序。您还应该可以阅读并理解以简单方 法使用线程的程序。

    java多线程编程_java多线程_

    2.讲解了在多线程中对并发访问的控制, 主要就是synchronized的使用, 由于此关键字在使用上非常灵活, 所以书中用了很多案例来介绍此关键字的使用, 为读者学习同步相关内容打好坚实的基础。3.介绍线程并不是孤独的...

    java线程.pdf

    本教程研究了线程的基础知识— 线程是什么、线程为什么有用以及怎么开始编写使用线程的简单 程序。 我们还将研究更复杂的、使用线程的应用程序的基本构件— 如何在线程之间交换数据、如何控制 线程以及线程如何互相...

    简单多线程 BackgroundWorker 控制(开始、暂停、继续、停止)

    1、简单多线程 BackgroundWorker 控制(开始、暂停、继续、停止) 2、刷新进度条提示 3、刷新文本框提示

    JAVA多线程编程详解-详细操作例子

    线程又称为轻量级进程,它和进程一样拥有独立的执行控制,由操作系统负责调度,区别在于线程没有独立的存储空间,而是和所属进程中的其它线程共享一个存储空间,这使得线程间的通信远较进程简单。 具体到java内存...

    java线程基础讲解

    本教程研究了线程的基础知识 — 线程是什么、线程为什么有用以及怎么开始编写使用线程的简单 程序。 我们还将研究更复杂的、使用线程的应用程序的基本构件 — 如何在线程之间交换数据、如何控制 线程以及线程如何...

    Java多线程程序设计详细解析

     线程又称为轻量级进程,它和进程一样拥有独立的执行控制,由操作系统负责调度,区别在于线程没有独立的存储空间,而是和所属进程中的其它线程共享一个存储空间,这使得线程间的通信远较进程简单。  多个线程的...

    键盘线程控制汽车限制在窗口内移动(源码+图片)

    键盘线程控制汽车限制在窗口内移动(源码+图片) 涉及到的方面有:线程、图片加载、键盘监听、Graphics画笔方法应用、图片的坐标控制等。...简单的小程序对联系面向对象有很多好处,适合java初学者学习并练习。

    Java线程(基础篇)

    本教程研究了线程的基础知识— 线程是什么、线程为什么有用以及怎么开始编写使用线程的简单 程序。 如何在线程之间交换数据、如何控制 线程以及线程如何互相通信。

    java多线程抽奖器

    这是一个用java写的简单抽奖器,运用多线程技术,并且通过读取文件控制各奖项的上限,内含详细代码及使用说明。

    java做的一个简单的抽奖机

    java做的抽奖机,用线程控制抽奖的滚动,不过还应不断完善,大家一块学习!!!

    java源码包---java 源码 大量 实例

     Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。 递归遍历矩阵 1个目标文件,简单! 多人聊天室 3...

    java如果如何进行多线程编程

    线程又称为轻量级进程,它和进程一样拥有独立的执行控制,由操作系统负责调度,区别在于线程没有独立的存储空间,而是和所属进程中的其它线程共享一个存储空间,这使得线程间的通信远较进程简单。

Global site tag (gtag.js) - Google Analytics