一.线程的基本概念
1.线程是一个程序内部的顺序控制流。
2.Java的线程是通过java.lang.Thread类来实现的。
3.VM启动时会有一个由主方法{public static void main(Args[] String)}所定义的线程。
4.可以通过创建新的Thread实例来创建新的线程。
5.每个线程都是通过某个特定的Thread对象所对应的方法run()来完成其操作的,方法run()称为线程体。
6.通过调用Thread类的start()方法来启动一个线程。
注意:多进程(在操作系统中能同时运行多个任务(程序));多线程(在同一应用程序中有多个顺序流同时执行)。
二.线程的建立
1.定义线程类,实现Runnable接口(推荐,更灵活):
Thread thread = new Threa(target); //target为Runnable接口类型;
Runnable中只有一个方法:public void run(); //用于定义线程运行体。
*使用Runnable接口可以为多个线程提供共享的数据。
在实现Runnable接口的类的run方法定义中可以使用Thread的静态方法:
public static Thread currentThread() 获取当前线程的引用。
public class ThreadTheory { public static void main(String args[]){ Runner1 runner1 = new Runner1(); Thread thread = new Thread(runner1); thread.start(); for(int i=0;i<10;i++){ System.out.println("Main Thread:"+i); } } } public class Runner1 implements Runnable { public void run() { for(int i=0;i<10;i++){ System.out.println("Runner1:"+i); } } }
2.继承Thread类,重写run方法:
class MyThread extends Thread{
public void run(){......}
}
然后生成该类的对象:
MyThread myThread = new MyThread(...);
public class ThreadTheory { public static void main(String args[]){ Runner2 runner2 = new Runner2(); runner2.start(); //runner2本身就是一个线程了,不用再new Thread(); for(int i=0;i<10;i++){ System.out.println("Main Thread:"+i); } } } public class Runner2 extends Thread { public void run() { for(int i=0;i<10;i++){ System.out.println("Runner2:"+i); } } }
三.线程控制的基本方法
sleep(thread.sleep(long millis))
public static void sleep(long millis) throws InterruptedException
- 在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)。该线程不丢失任何监视器的所属权。
- 参数:
millis
- 以毫秒为单位的休眠时间。- 抛出:
InterruptedException
- 如果另一个线程中断了当前线程。当抛出该异常时,当前线程的中断状态 被清除。
interrupt(thread.interrupt())
public void interrupt()
- 中断线程。
如果当前线程没有中断它自己(这在任何情况下都是允许的),则该线程的
checkAccess
方法就会被调用,这可能抛出SecurityException
。如果线程在调用
Object
类的wait()
、wait(long)
或wait(long, int)
方法,或者该类的join()
、join(long)
、join(long, int)
、sleep(long)
或sleep(long, int)
方法过程中受阻,则其中断状态将被 清除,它还将收到一个InterruptedException
。如果该线程在
可中断的通道
上的 I/O 操作中受阻,则该通道将被关闭,该线程的中断状态将被设置并且该线程将收到一个
ClosedByInterruptException
。如果该线程在一个
Selector
中受阻,则该线程的中断状态将被设置,它将立即从选择操作返回,并可能带有一个非零值,就好像调用了选择器的wakeup
方法一样。如果以前的条件都没有保存,则该线程的中断状态将被设置。
- 抛出:
SecurityException
- 如果当前线程无法修改该线程
join
public final void join() throws InterruptedException
- 等待该线程终止。(相当于把线程添加到当前主线程,相当于调用该线程,等该线程执行结束,再回到主线程)
- 抛出:
InterruptedException
- 如果另一个线程中断了当前线程。当抛出该异常时,当前线程的中断状态 被清除。
yield
public static void yield()
- 暂停当前正在执行的线程对象,并执行其他线程。(让出当前线程的时间片,但是仅仅是一个时间片)
public class TestYield { public static void main(String[] args) { MyThread3 thread1 = new MyThread3("t1"); MyThread3 thread2 = new MyThread3("t2"); thread1.start(); thread2.start(); } } class MyThread3 extends Thread { MyThread3(String s){ super(s); } public void run(){ for(int i=0;i<100;i++){ System.out.println(getName()+":"+i); if(i%10 == 0){ yield(); } } } }
线程的优先级Priority
线程提供一个线程调度器来监控程序中启动后进入就绪状态的所有线程。线程调度器按照线程的优先级决定应调用哪个线程来执行。
线程的优先级用数字表示,范围从1到10,缺省的优先级是5:
THREAD.MIN_PRIORITY = 1;
THREAD.MAX_PRIORITY = 10;
THREAD.NORM_PRIORITY = 5;
可以用以下方法来处理线程的优先级:
int getPriority();
void setPriority(int newPriority);
注意:舒适的结束线程的方法(拒绝暴力):
public class ThreadTheory { public static void main(String args[]){ MyThread myThread = new MyThread(); myThread.start(); try{ Thread.sleep(10000); }catch(InterruptedException e){} myThread.stopThread(); //通过标志去结束线程 } } public class MyThread extends Thread { private boolean flag = true; public void stopThread(){ this.flag = false; } public void run() { while(flag){ System.out.println("===当前时间"+ new Date() + "==="); try{ sleep(1000); }catch(InterruptedException e){ return; } } } }