谈谈java中的线程(初级概念)
定义
关于进程与线程的定义 可参看一下这个介绍http://www.ruanyifeng.com/blog/2013/04/processes_and_threads.html
在不细抠定义的情况下
我们可以认为 在操作系统里一个任务就是一个进程 像word,qq都可以看做一个进程.
另一方面如果这个进程内部的函数调用 就是一条线 那它就是单线程
如果有多条线 那就是多线程 而在这个进程内部 每一条执行的流程就叫做一个线程
我们自己定义的线程
在自定义线程之前 我们先看看java里关于线程的一些类主要有两个
一个是interface Runnable
里面只有一个方法run()
一个是class Thread
其实它也实现了Runnable接口(也就必须重写了run方法),同时它还有一个方法叫start
来我们看第一个例子 顺便讲讲start与run的区别
public class TestThread1 { public static void main(String args[]) { Runner1 r = new Runner1(); r.start(); //r.run(); for(int i=0; i<100; i++) { System.out.println("Main Thread:------" + i); } } } class Runner1 extends Thread { public void run() { for(int i=0; i<100; i++) { System.out.println("Runner1 :" + i); } } }运行的结果是 Main Thread..与Runner1...交替输出
这时候 就运行了两个线程 一个主线程 一个r线程
如果把r.start改成r.run那么就是先打出100个Runner1..然后才是100个Main Thread
为什么?
大家仔细看看如果我们调用r.run() 那不就是函数调用了么!!!
所以一句话我们自定义的线程必须实现run方法 但调用的时候得是start()!
再看另一种定义线程的方式
public class TestThread1 { public static void main(String args[]) { Runner1 r = new Runner1(); Thread t = new Thread(r); t.start(); for(int i=0; i<50; i++) { System.out.println("Main Thread:------" + i); } } } class Runner1 implements Runnable { public void run() { for(int i=0; i<50; i++) { System.out.println("Runner1 :" + i); } } }
两种定义线程的方式 我们选择哪一种?
选第二种 实现Runable接口的方式
因为我们一旦继承了Thread类 就不能再继承别的类了
因此能继承类能实现接口的时候就选实现接口的方式
sleep interrupt stop flag
public class TestThread3{ public static void main(String args[]) { Runner3 r = new Runner3(); Thread t = new Thread(r); t.start(); } } class Runner3 implements Runnable { public void run() { for(int i=0; i<30; i++) { if(i%10==0 && i!=0) { try{ Thread.sleep(2000); }catch(InterruptedException e){} } System.out.println("No. " + i); } } }
看这个例子 它运行的结果是 先马上打印出0-9然后停两秒再打印出10-19...
Thread.sleep()就是让程序休眠一段时间 时间的长短由参数指定 单位为毫秒
不过要注意 sleep会抛出InterruptedException异常
public class TestInterrupt { public static void main(String[] args) { MyThread thread = new MyThread(); thread.start(); try {Thread.sleep(10000);} catch (InterruptedException e) {} thread.interrupt(); } } class MyThread extends Thread { boolean flag = true; public void run(){ while(true){ System.out.println("==="+new Date()+"==="); try { sleep(1000); } catch (InterruptedException e) { return; } } } }
这段代码的结果是 每隔一秒输出当前的时间 等运行了10秒后停止
大家也看到了 sleep本身可能会被"打扰" 就是interrupt 我们在主线程里调用了 thread.interrupt();
等于就抛出了异常 那么thread就只能执行catch里面的代码 return了
另外 Thread还有一个方法叫stop(已废弃) 看名字 我们就知道它能干什么了
不过他比interrupt还粗暴 interrupt毕竟还有一个catch呢 在结束之前 还能干点事 stop就完全没有做其他事的机会了
当然要结束这种"死循环"的线程 也不难
MyThread里面加一个Boolean型的flag 令其为true while(true)改成while(flag)
想结束的时候 在主函数里让flag=false 即可
join yield priority
public class TestInterrupt { public static void main(String[] args) { MyThread thread = new MyThread(); thread.start(); try {Thread.sleep(10000);} catch (InterruptedException e) {} thread.interrupt(); } } class MyThread extends Thread { boolean flag = true; public void run(){ while(true){ System.out.println("==="+new Date()+"==="); try { sleep(1000); } catch (InterruptedException e) { return; } } } }
通过查看这个代码的结果 就明白 join就是把线程合并
如上 就是等ti的run执行完毕后 主线程再继续往下走 有点把线程调用看成函数调用的感觉
只有Thread的yield()方法就是线程主动放弃他所拥有的时间片 让其他线程使用 (当然只是放弃一次 下一次有了时间片 它就不放弃了)
代码如下
public class TestInterrupt { public static void main(String[] args) { MyThread thread = new MyThread(); thread.start(); try {Thread.sleep(10000);} catch (InterruptedException e) {} thread.interrupt(); } } class MyThread extends Thread { boolean flag = true; public void run(){ while(true){ System.out.println("==="+new Date()+"==="); try { sleep(1000); } catch (InterruptedException e) { return; } } } }
运行时会发现 每当一个线程打印出自己的名字和整10的序号的时候 下一个运行的都不是自己 yield() 它放弃了本次对时间片的使用
只于priority(优先级) 有两个方法setPriority getPriority
priority 从1到10 10为最高
priority越高 获得时间片的几率越大
代码如下
public class TestPriority { public static void main(String[] args) { Thread t1 = new Thread(new T1()); Thread t2 = new Thread(new T2()); t1.setPriority(Thread.NORM_PRIORITY + 3); t1.start(); t2.start(); } } class T1 implements Runnable { public void run() { for(int i=0; i<1000; i++) System.out.println("T1: " + i); } } class T2 implements Runnable { public void run() { for(int i=0; i<1000; i++) System.out.println("------T2: " + i); } }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。