java多线程编程
在多线程编程下,对处理并发时,可能产生重复工作的线程,
首先,从基础的说起
第一步如何创建一个线程、运行一个线程
Tread thread = new Thread();
thread.start();
第二步,在线程里实现功能
这里大部分部分内容参考了http://ifeve.com/creating-and-starting-java-threads/
由于,线程启动之后会自动运行run()函数里的代码,所以需要实现功能有两种方式:
一种是创建Thread子类的一个实例并重写run方法
public class MyThread extends Thread {
public void run(){
System.out.println("MyThread running");
}
}
可以用如下方式创建并运行上述Thread子类
MyThread myThread = new MyThread();
myTread.start();
创建匿名类的方式
Thread thread = new Thread(){
public void run(){
System.out.println("Thread Running");
}
};
thread.start();
第二种是创建类的时候实现Runnable接口:
public class MyRunnable implements Runnable {
public void run(){
System.out.println("MyRunnable running");
}
}
为了使线程能够执行run()方法,需要在Thread类的构造函数中传入 MyRunnable的实例对象。示例如下:
Thread thread = new Thread(new MyRunnable());
thread.start();
匿名类实现:
Runnable myRunnable = new Runnable(){
public void run(){
System.out.println("Runnable running");
}
}
Thread thread = new Thread(myRunnable);
thread.start();
具体这两种的比较,网上有很多资料可以查,但有一点: 因为线程池可以有效的管理实现了Runnable接口的线程,如果线程池满了,新的线程就会排队等候执行,直到线程池空闲出来为止。而如果线程是通过实现Thread子类实现的,这将会复杂一些,有时需要两种方式都用。
常见错误:调用run()方法而非start()方法
创建并运行一个线程所犯的常见错误是调用线程的run()方法而非start()方法,如下所示:
Thread newThread = new Thread(MyRunnable());
newThread.run(); //should be start();
事实上,run()方法并非是由刚创建的新线程所执行的,而是被创建新线程的当前线程所执行了。也就是被执行上面两行代码的线程所执行的。想要让创建的新线程执行run()方法,必须调用新线程的start方法。
第三步,向线程中传递参数
一般来说,线程中处理的事务多数需要外界参数,这里有三种方法,具体参考
http://www.jb51.net/article/31981.htm
第四步,在多线程环境下,找到指定命名的当前运行的线程
第一点是给线程命名 当创建一个线程的时候,可以给线程起一个名字。它有助于我们区分不同的线程。例如:如果有多个线程写入System.out,我们就能够通过线程名容易的找出是哪个线程正在输出。例子如下:
MyRunnable runnable = new MyRunnable();
Thread thread = new Thread(runnable, "New Thread");
thread.start();
System.out.println(thread.getName());
需要注意的是,因为MyRunnable并非Thread的子类,所以MyRunnable类并没有getName()方法。可以通过以下方式得到当前线程的引用:
Thread.currentThread();
因此,通过如下代码可以得到当前线程的名字:
String threadName = Thread.currentThread().getName();
线程代码举例: 这里是一个小小的例子。首先输出执行main()方法线程名字。这个线程JVM分配的。然后开启10个线程,命名为1~10。每个线程输出自己的名字后就退出。
public class ThreadExample {
public static void main(String[] args){
System.out.println(Thread.currentThread().getName());
for(int i=0; i<10; i++){
new Thread("" + i){
public void run(){
System.out.println("Thread: " + getName() + "running");
}
}.start();
}
}
}
需要注意的是,尽管启动线程的顺序是有序的,但是执行的顺序并非是有序的。也就是说,1号线程并不一定是第一个将自己名字输出到控制台的线程。这是因为线程是并行执行而非顺序的。Jvm和操作系统一起决定了线程的执行顺序,他和线程的启动顺序并非一定是一致的。
第二点是找到对应名称的线程
在多线程编程中,处理并发情况下,很容易出现某一个线程的内容重复使用,如果线程使用率较高,或者某个线程具有延迟等功能的话,多次创建新的线程不利于线程管理,也容易造成阻塞,所以,在这些线程的过程中需要判断,当前运行的线程中是否有对应名字的线程
下面代码用于取得所有的正在运行线程的名字:
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);
// copy into a list that is the exact size
Thread[] list = new Thread[actualSize];
System.arraycopy(slackList, 0, list, 0, actualSize);
System.out.println("Thread list size == " + list.length);
for (Thread thread : list) {
System.out.println(thread.getName()); //这里取得名字后可以进行逻辑操作
}
这里其实有个问题,因为拿到的是所有线程,包括父线程,所以当同一时间运行程序很多的时候可能会拿到大量无用的线程,
在工程中可以建立一个静态列表,在创建某个线程的时候,把命名放在这个列表里面,然后在搜素的时候可以先查列表,如果只是知道某个线程在不在启动,则可以用这个简便算法
最后再次感谢
http://ifeve.com/creating-and-starting-java-threads/
http://www.jb51.net/article/31981.htm
http://trinityblood.iteye.com/blog/1618181
三位作者的大力支持
相关文章
- java volatile关键字的作用_Java并发编程彻底搞懂volatile关键字「建议收藏」
- java用什么软件_Java编程什么软件最好用?
- java 音频转为wav格式标准音频 | Java工具类
- java多线程编程实例
- java locale 中国_Java描述语言、国家和地理的类——Locale
- java是面向对象还是面向过程_Java面向对象编程和面向过程编程的区别[通俗易懂]
- MySQL字段类型如何转为java_Java JDBC中,MySQL字段类型到JAVA类型的转换
- Java 多线程
- java notifyall_Java Thread notifyAll()方法[通俗易懂]
- Deep Java Library_java atomicinteger
- JAVA程序员简历模板_Java工程师简历模板
- Java面试集锦(一)之Java多线程
- Java 多线程并发编程之 Synchronized 关键字详解编程语言
- Java多线程编程——进阶篇一详解编程语言
- Java多线程5:synchronized锁方法块详解编程语言
- Java多线程2:Thread中的实例方法详解编程语言
- Linux下Java编程之旅(linux执行java)
- Oracle转Java实现跨平台开发的奇妙之旅(oracle转java)
- Java 连接 Redis:实现数据快速传输(java连redis)
- Linux调用Java实现编程快速开发(linux调用java)
- Linux和Java联手构建编程世界(linux.java)
- 基于Linux操作系统上实现 Java 编程(linux r java)
- Linux与Java结合:开启全新的编程之旅(linux java())
- Java编程与Oracle技术创造技术价值的奥秘(java编程oracle)
- 的应用Java在Oracle数据库中的重要性及应用(java在oracle里)
- java多线程并发executorservice(任务调度)类
- java多线程编程之线程的生命周期