java多线程:创建、join方法
来源:互联网 发布:买家怎么取消农村淘宝 编辑:程序博客网 时间:2024/06/03 19:32
一、进程和线程的区别
进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1–n个线程。
线程:同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换开销小。
线程和进程一样分为五个阶段:创建、就绪、运行、阻塞、终止。
新建状态(New):新建的线程处于新建状态,如:Thread t = new MyThread();
就绪状态(Runnable):当调用线程对象的start()方法(t.start();),线程即进入就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,随时等待CPU调度执行,并不是说执行了t.start()此线程立即就会执行;
运行状态(Running):当CPU开始调度处于就绪状态的线程时,此时线程才得以真正执行,即进入到运行状态。注:就 绪状态是进入到运行状态的唯一入口,也就是说,线程要想进入运行状态执行,首先必须处于就绪状态中;
阻塞状态(Blocked):处于运行状态中的线程由于某种原因,暂时放弃对CPU的使用权,停止执行,此时进入阻塞状态,直到其进入到就绪状态,才 有机会再次被CPU调用以进入到运行状态。根据阻塞产生的原因不同,阻塞状态又可以分为三种:
1.等待阻塞:运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态;
2.同步阻塞 – 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态;
3.其他阻塞 – 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。
二、实现线程的方式:
JAVA多线程实现方式主要下面几种:继承Thread类、实现Runnable接口、实现Callable接口、使用ExecutorService。
三、线程调度
Java线程优先级高的线程会获得较多的运行机会
Java线程的优先级用整数表示,取值范围是1~10,Thread类有以下三个静态常量:
static int MAX_PRIORITY:线程可以具有的最高优先级,取值为10。
static int MIN_PRIORITY:线程可以具有的最低优先级,取值为1。
static int NORM_PRIORITY:分配给线程的默认优先级,取值为5。
每个线程都有默认的优先级,缺省优先级为 NORM_PRIORITY。
有关优先级的方法有两个:
final void setPriority(int newp) : 修改线程的当前优先级
final int getPriority() : 返回线程的优先级
主线程的默认优先级为Thread.NORM_PRIORITY。
线程的优先级有继承关系,比如A线程中创建了B线程,那么B将和A具有相同的优先级。
JVM提供了10个线程优先级,但与常见的操作系统都不能很好的映射。如果希望程序能移植到各个操作系统中,
应该仅仅使用Thread类有以下三个静态常量作为优先级,这样能保证同样的优先级采用了同样的调度方式。
//main方法也是一个线程 是普通优先级public class Test { public static void main(String[] args) throws InterruptedException { ThreadTest t1=new ThreadTest(); t1.setName("线程1");//设置线程的名称 t1.start();//启动线程 不能直接调用run方法// t1.sleep(3000); ThreadTest t2=new ThreadTest(); t2.setName("线程2"); t2.start();// t2.start();//不能两次调用start方法// t2.setPriority(10);//设置线程对象的优先级 参数的范围是0-10 默认为5 数值越大表示执行的时间越长的概率越高// t1.setPriority(1);// t1.setPriority(Thread.NORM_PRIORITY);//也可以使字段常量 MAX_PRIORITY MIN_PRIORITY NORM_PRIORITY /*Thread t = Thread.currentThread();//获得当前正在执行的线程对象 for(int i=0;i<600;i++){ System.out.println(t.getName()+" "+i); }*/ }}//线程:继承Thread类 重写run方法class ThreadTest extends Thread{ @Override public void run() { for(int i=0;i<5000;i++){ /*if(i==100){ try { sleep(2000);//让线程对象休眠 参数是毫秒数 } catch (InterruptedException e) { e.printStackTrace(); } }*/ yield();//谦让 暂停当前正在执行的线程对象,并执行其他线程 System.out.println(this.getName()+" "+i);//获得线程的名称 } } }
四、线程join方法
join()方法,等待其他线程终止。在当前线程中调用另一个线程的join()方法,则当前线程转入阻塞状态,直到另一个进程运行结束,当前线程再由阻塞转为就绪状态。
//线程对象互相join 也会死锁public class Test1 { public static void main(String[] args) { Thread1 t1=new Thread1(); Thread2 t2=new Thread2(); t1.t2=t2;//给线程对象的属性赋值 t1.setName("线程1"); t2.t1=t1; t2.setName("线程2"); t1.start(); t2.start(); }}class Thread1 extends Thread{ Thread2 t2; @Override public void run() { for(int i=0;i<500;i++){ if(i==400){ try { t2.join(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println(getName()+" "+i); } }}class Thread2 extends Thread{ Thread1 t1; @Override public void run() { for(int i=0;i<500;i++){ if(i==100){ try { t1.join();//让出当前线程 让t1线程对象执行完 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println(getName()+" "+i); } }}
参考资料:
Java总结篇系列:Java多线程(一)
- java多线程:创建、join方法
- java多线程-join方法
- Java 多线程join方法
- java多线程join方法
- java多线程中join()方法
- java多线程 中的join方法
- java多线程之join()方法
- java多线程之join()方法
- Java笔记 - 多线程 - Join方法
- Java多线程的join方法
- Java多线程系列-join方法
- java多线程创建方法
- 深入浅出Java多线程(1)-方法 join
- 深入浅出Java多线程(1)-方法 join
- java多线程中的join方法详解
- 初学Java多线程:join方法的使用
- 初学Java多线程:join方法的使用
- java多线程中的join方法详解
- 关于python里面的对齐
- 短信发送器
- hdu 5877 Weak Pair dfs + 线段树(or树状数组)
- LeetCode 24. Swap Nodes in Pairs
- 手游服务端开发基础概念扫盲篇
- java多线程:创建、join方法
- FTP 限制用户只访问HOME目录
- chrome 中的console 下无法使用jquery选择器
- Android操作GPIO
- mac 编译《unix网络编程》 的libunp.a
- 《民主的细节》摘录
- ps的基础介绍(没完,后续)
- 偏函数GUI程序
- 单一职责之ImageLoader(二)