java线程基础

来源:互联网 发布:逆战ak12淘宝多少钱 编辑:程序博客网 时间:2024/06/03 17:15

java线程之基础

Thread类的基本方法介绍:

Thread()  使用默认值来创建一个线程对象

Thread(Runnable target)    创建一个和给定Runnable对象相关联的线程对象。

Thread(String name)     创建一个线程对象,同时赋予其一个名字。该构造方法只适用于通过继承来创建线程对象。

Thread(Runnable target,String name)    创建一个线程对象,在将其与一个Runnable对象相关联的同时赋予其一个名字。

void run()  运行刚刚创建的线程,程序员应该用自己的代码来覆盖这个方法。默认实现的本质是一个空的方法。

void start()   创建一个新线程并执行线程类中定义的run()方法。

void stop()    (不鼓励使用)停止一个运行的线程。

static void sleep(long milliseconds)   使得正在运行的线程睡眠指定的毫秒。

static void sleep(long milliseconds,intnanoseconds)  使得正在运行的线程睡眠指定的毫秒和纳秒。

boolean isAlive()   确定一个线程是不是活动的。

void join()     等待指定的线程执行结束。当一个线程不活动/压根没有启动时,立即返回。

void join(long timeout)   等待指定的线程执行结束,但是不超过指定的毫秒。

void join(long timeout,int nanaos)   等待指定的线程执行结束,但是不超过指定的毫秒和纳秒。

void setName(String name)   为Thread 实例指定名字。

String getName()    获得Thread实例的名字。

static Thread currentThread()  获取当前运行的Thread 对象。

static int enumerate(Thread threadArray[])  获取程序中的线程对象,并且将它们出彩在一个线程数组中。返回值是实际存储在线程数组中的线程个数。

static int activeCount()    返回程序中线程的个数。

 

    以上方法中是静态方法,才能直接通过Thread类名直接调用。为什么呢?因为如果方法是静态的话,在类加载时候就创建内存地址了,不需要类的实例化。

         另外,java的静态变量开始于类的创建,结束于类的消亡。非静态变量叫做实例变量,它开始于类的实例的创建,结束于类的实例的消亡,静态变量被所有实例所共享。

         从内存的角度分析,当一个类被创建并初始化后,内存中会有两个区域,栈区和堆区。栈中主要存放的是引用变量,堆中主要存放的是真实的被实例化后的类。栈中的引用变量会指向堆中的真实对象地址。比如 A a=new A();引用变量a存放在栈区中,实际new出来的类A的对象放在堆中,a指向实际被new出来的A对象。

         一个类中有静态变量,程序首先会把该变量加载进内存中,也就是在堆中开辟一个区域专门存放。以后不管new出来多少个类对象,它们的静态变量存放位置不变。

         在这里我们应该就知道为什么静态方法中不能调用非静态方法了吧。因为静态方法首先被加载到内存中,而我们要用类直接调用非静态方法的时候,发现他却引用了非静态的方法,肯定会出错。

回归到线程的问题来,我们知道实现多线程有两种基本的方法,一种是继承类Thread一种是实现接口Runnable

下面是继承Thread,同时加入了计时器的简单代码:

package com.demo;public class java_thread {public static int cout_1 = 1;public static class OurClass extends Thread{private  boolean shouldRun;private int sleep_time;private AnotherClass anotherclass;public OurClass(int sleep_time,AnotherClass anotherclass){this.sleep_time=sleep_time;this.anotherclass=anotherclass;this.shouldRun=true;}public void run(){while(shouldRun){try{anotherclass.init();sleep(sleep_time);}catch(Exception e){}}}}public static class AnotherClass {public void init(){for(int i=0;i<100;i++){System.out.println("hello world"+cout_1);}cout_1++;}}/** * @param args */public static void main(String[] args) {// TODO Auto-generated method stubAnotherClass anotherclass = new AnotherClass();OurClass oc = new OurClass(2000,anotherclass);oc.start();}}

实现接口Runnable的简单代码:

package com.demo;public class java_thread {public static int cout_1 = 1;public static class OurClass implements Runnable{private  boolean shouldRun;private int sleep_time;private AnotherClass anotherclass;public OurClass(int sleep_time,AnotherClass anotherclass){this.sleep_time=sleep_time;this.anotherclass=anotherclass;this.shouldRun=true;}public void run(){while(shouldRun){try{anotherclass.init();Thread.sleep(sleep_time);}catch(Exception e){}}}}public static class AnotherClass {public void init(){for(int i=0;i<100;i++){System.out.println("hello world"+cout_1);}cout_1++;}}public static void main(String[] args) {// TODO Auto-generated method stubAnotherClass anotherclass = new AnotherClass();OurClass oc = new OurClass(2000,anotherclass);Thread th =new Thread(oc);th.start();}}

以上的例子中,我们通过对shouldRun赋值来达到停止线程的目的,但是事实上,我们不能马上停止进程,假如睡眠时间很长的话,假如刚刚睡眠,我们恰巧在此时试图停止线程,那么需要等待线程醒来去判断shouldRun才会停止线程。这显然在某些情况下是危险的,那么我们可以使用Thread class的interrupt()方法来中断任何的blocking method。

interrupt()方法有两个效应

1,它会导致任何的blocked method抛出异常,我我们的范例中,sleep()方法就是一个blocking method,如果处理事件的thread 在执行sleep()方法的时候中断,此sleep会立即被唤醒并抛出一个InterruptedException。具有此行为的method包括了wait(),join()以及读取I/O的method。

2,设定thread对象内部的标记来指示此thread已经被中断。课使用isInterrupted()方法来查询这个标记。

所以上面的例子 可以改为 while(isInterrupted()){ }。

不过 上述方法也绝非不是完美的,假如线程执行了isInterrupted()同时也没有进入睡眠的状态,那么调用interrupt()自然不会产生异常啦,所以还要继续睡觉。


 

原创粉丝点击