一、使用线程的三种方式
第一种:继承Thread类(用的比较少)
public class ThreadOfMine extends Thread {
public ThreadOfMine(String name){
super.setName(name);//此处是为线程起一个名字,我随便搞了一个
}
@Override
public void run() {
super.run();//@第二步
System.out.println("mythread:"+this.currentThread().getName());
}
//main方法是执行入口,首先是start方法
public static void main(String[] args) {
ThreadOfMine threadOfMine = new ThreadOfMine("第一次");
threadOfMine.start();//@第一步
System.out.println("开始运行");
}
}
结果:
开始运行
mythread:第一次
注意:这个thread类不是一个抽象类,run也不是抽象方法
可以看出Thread也实现了Runnable接口,而且,这个run方法竟然是重写方法,说明这个方法的源头应该是Runnable接口中的。再上图
然后这个Runnable里面竟然只有一个方法,并且只有这么一个抽象方法,我也是醉了
第二种:实现Runnable接口
个人感觉这种方法优于第一种,因为java是单继承的,然而可以实现很多个接口。
代码示例:
public class ThreadOfMine implements Runnable {
@Override
public void run() {
// 由于这个runnable接口中只有一个抽象方法,所以我们实现以后就直接运行吧,super什么的也没用了
// 象征性的打一句话
System.out.println("第二种方法Runnable");
}
public static void main(String[] args) {
Runnable runnable=new ThreadOfMine();
Thread t1=new Thread(runnable);
t1.start();
System.out.println("开始运行");
}
结果
开始运行
第二种方法Runnable
第三种:线程池方法
这个方法几乎是用的最多的
二、线程中的常用方法
currentThread() 返回当前正在执行的线程对象的引用
getId() 返回此线程的标识符
getname()返回此线程的名称
getPriority()返回此线程的优先级
isAlive 判断此线程是否活跃(就是正在运行或者就绪状态)
sleep(long mi) 参数是毫秒数,与秒是千位换算,1s=1000毫秒
interrupt 中断这个线程
interrupted和isinterrupted()
前者是测试当前进程是否是中断状态,执行后具有将状态标志清除为false的功能,后者只是判断是否中断,不具有清除状态标志的功能
setName() 上面的例子中已经使用过,更改线程名字
join() 等待线程终止。使用情况就是
在很多情况下,主线程生成并启动了子线程,如果子线程里要进行大量的耗时的运算,主线程往往将于子线程之前结束,但是如果主线程处理完其他的事务以后,需要用到子线程的处理结果,也就是主线程需要等待子线程执行完成之后再结束,这个时候就要用到join()方法了。
举例:线程a是主线程,线程b是子线程,他们共同服务一个客户,主线程干完了其他的事情,但是b还没有执行完,那么主线程a就不能结束,他必须等待b执行完成以后,再继续执行一些其他操作(比如用到线程b中的处理结果)。也就是说b.join()就是后面所需要执行的操作,只有在b执行完了以后才能执行。
yield() 放弃当前cpu资源,将它让给其他的任务去占用cpu。
有什么补充的请指教。。。