java中多线程统计时间_java线程一之建立线程、线程池以及多线程运行时间统计...

线程和进程的基本概念

进程和线程是动态的概念。 html

进程是 “执行中的程序“,是一个动词,而程序是一个名词,进程运行中程序的”代码“,并且还有本身的计数器,寄存器,它会向系统申请系统资源。 java

线程是进程中的一个控制流。一个程序可能可能包含多个任务并发运行,而线程就是指一个任务重头到尾的执行流。 多线程

说的在简单点,线程是执行中的任务,一个程序包含多个任务。 并发

多线程

单处理器中,为提升处理器的使用率(最终目标),使得程序在进行IO输入出等不须要处理器时,也可以让处理器在运转,引进多线程处理机制。多线程可使得程序运行的更快,执行效率更高,交互性更强,这是不言而喻的! ide

建立任务和线程

一个任务是一个对象,因此为建立一个任务,必须定义一个类,定义一个任务类,为了说明这是一个任务类,它须要实现Runnable接口,这个接口只包含一个run方法。 学习

当咱们定义好任务类taskClass以后,就能够用它的构造方法建立一个任务啦:TaskClass  task = new TaskClass(.....); this

咱们建立的任务只能在线程中运行,Thread类中包含了建立线程以及控制线程的众多方法。使用下面的语句建立任务线程:Thread  thread  = new Thread(task); 线程

而后调用start()方法告诉java虚拟机该线程准备运行:thread.start();以后java虚拟机经过调用任务的run()方法执行任务。 设计

事例代码:htm

public class TaskThreadDemo{

public static void main(String[] args)

{

//建立任务 而且须要为任务 建立 任务类,使用该类的构造方法建立任务

PrintChar printA = new PrintChar('a',100);

PrintChar printB = new PrintChar('b',100);

PrintNum print100 = new PrintNum(100);

//为任务建立线程

Thread thread1 = new Thread(printA);

Thread thread2 = new Thread(printB);

Thread thread3= new Thread(print100);

//告诉虚拟机器线程开始运行

thread1.start();

thread2.start();

thread3.start();

}

}

class PrintChar implements Runnable

{

private char charToPrint;

private int items;

public PrintChar(char c,int t)

{

charToPrint = c;

items = t;

}

@Override

public void run() {

// TODO Auto-generated method stub

for(int i=0;i

{

System.out.print(charToPrint);

}

}

}

class PrintNum implements Runnable

{

private int lastNumb;

public PrintNum(int n)

{

lastNumb = n;

}

@Override

public void run() {

// TODO Auto-generated method stub

for(int i= 1;i<100;i++)

{

System.out.print(" "+lastNumb);

}

}

}

adb02f5fa6579f4bf9d8446f8c06c057.png

一个好玩的闪烁文本框,直接用线程,不用main方法

import javax.swing.JApplet;

import javax.swing.JLabel;

public class FlashingText extends JApplet implements Runnable {

private static final long serialVersionUID = 1L;

private JLabel jlbText = new JLabel("Welcome",JLabel.CENTER);

public FlashingText()

{

add(jlbText);

new Thread(this).start();

}

public void run()

{

try {

while(true)

{

if(jlbText.getText()==null)

jlbText.setText("Welcome");

else

jlbText.setText(null);

Thread.sleep(200);

}

} catch (Exception e) {

// TODO: handle exception

}

}

}

3ddeeee8b3d2cd778783b1a9a48cb666.png341cbf625dfa45a9d2e665917cd6fbcd.png

Thread类

Thread类实现了Runnable接口,它包含为任务而建立线程的构造方法,以及控制方法,下图就是Thread类常见的控制线程的方法:

03eb19554c8d99e7e1cd1e323c68cf4e.png

由于Thread类实现了Runnable接口,因此能够定义一个Thread的扩展类,里面实现run方法,这样也能够建立一个线程类,但并非很推荐这种方法,由于它将建立任务和运行任务的机制混在了一块儿,将任务从线程中分离出来比较好,即尽可能使用Runnable接口建立线程,这样获得的线程更加灵活,避免了java单继承带来的局限性。

线程池

线程池是管理并发执行任个数的理想方法,java提供Executor接口来执行线程池中的任务,提供ExecutorService接口来管理和控制任务。为了建立Executor接口实例,咱们能够用Executors类,Executors类提供了建立Executor接口对象的静态方法,下图描述了上面的上面所说的关系。

2b9a70db383286de43485502cc0b7ba7.png

线程池中的shutdown()方法通常都是放在main方法的后面部分,当因此的线程都添加到线程池中,即使有线程没有执行完毕,也可能会关闭线程池,未执行完的线程继续执行,因此main方法可能比子线程先结束。

利用isTerminated()进行线程池中全部线程运行时间的统计

假若但愿主线程在子线程所有作完以后在执行,能够考虑让因此的子线程用jion方法,但这可能致使全部子线程变成串行,不是很好的办法,固然咱们也能够多线程的辅助类CountDownLatch,这是一个与计时器有点相似功能的类。此次在看书学习的时候,发现了一个更好的办法,就是在shutdown()方法后加上一句while(!executor.isTerminated()){},这是一个不错的方法(不过我把shoudown()方法放在该while语句后面,就会陷入死循环,应该是要先关闭线程池,在判断线程池中的线程是否所有终止,由于也有可能在while语句后面在添加新的子线程)。

isTerminated()方法:若是线程池中因此线程都已完成并终止,则返回true.

可使用CountDownLatch 和上面的方法对程序运行计时统计,不过我记得CountDownLatch类是须要指定线程的个数。

事例代码

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

public class ExecutorDemo {

public static void main(String[] args){

long start = System.currentTimeMillis();

System.out.println("当前时间"+" "+start);

ExecutorService executor = Executors.newFixedThreadPool(4);

executor.execute(new PrintChar('a',100));

executor.execute(new PrintChar('b',100));

executor.execute(new PrintChar('c',100));

executor.execute(new PrintNum(100));

executor.shutdown();

while(!executor.isTerminated()){

//System.out.print("-");

};

long end = System.currentTimeMillis();

System.out.println("\n当前时间"+" "+end);

System.out.println("\n用时"+" "+(end-start)+"毫秒");

}

}

运行截图

820db78bfa0898c4e7773980156e2c16.png 截图1      b82e9b80317c9594d050272be7530c34.png截图2

不过不知道运行太快的缘由,仍是啥别的缘由, 会出现截图2的状况,网上不多关于isTerminated()方法的介绍,若有大神知道缘由,还请告知小弟。

这篇博客是本身在学习《java语言程序设计进阶篇》时所在笔记,代码出自书上,最后那个记时的加了计时部分。大三开学在即,但愿如今来学java还来得及。

本文出自于博客园兰幽,转载请说明出处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值