作个笔记,java线程经常使用的方法,耐心看完.javascript
编号 | 方法 | 说明 |
---|---|---|
1 | public void start() |
使该线程开始执行;Java 虚拟机调用该线程的 run 方法。 |
2 | public void run() |
若是该线程是使用独立的 Runnable 运行对象构造的,则调用该 Runnable 对象的 run 方法;不然,该方法不执行任何操做并返回。 |
3 | public final void setName(String name) |
改变线程名称,使之与参数 name 相同。 |
4 | public final void setPriority(int priority) |
更改线程的优先级。 |
5 | public final void setDaemon(boolean on) |
将该线程标记为守护线程或用户线程。 |
6 | public final void join(long millisec) |
等待该线程终止的时间最长为 millis 毫秒。 |
7 | public void interrupt() |
中断线程。 |
8 | public final boolean isAlive() |
测试线程是否处于活动状态。 |
9 | public static void yield() |
暂停当前正在执行的线程对象,并执行其余线程。 |
10 | public static void sleep(long millisec) |
在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操做受到系统计时器和调度程序精度和准确性的影响。 |
11 | public static Thread currentThread() |
返回对当前正在执行的线程对象的引用。 |
currentThread()方法能够返回代码段正在被哪一个线程调用的信息。java
public class Run1{ public static void main(String[] args){ System.out.println(Thread.currentThread().getName()); } }
方法sleep()的做用是在指定的毫秒数内让当前“正在执行的线程”休眠(暂停执行)。这个“正在执行的线程”是指this.currentThread()返回的线程。面试
sleep方法有两个重载版本:多线程
sleep(long millis) //参数为毫秒 sleep(long millis,int nanoseconds) //第一参数为毫秒,第二个参数为纳秒
sleep至关于让线程睡眠,交出CPU,让CPU去执行其余的任务。
可是有一点要很是注意,sleep方法不会释放锁,也就是说若是当前线程持有对某个对象的锁,则即便调用sleep方法,其余线程也没法访问这个对象。看下面这个例子就清楚了:ide
public class Test { private int i = 10; private Object object = new Object(); public static void main(String[] args) throws IOException { Test test = new Test(); MyThread thread1 = test.new MyThread(); MyThread thread2 = test.new MyThread(); thread1.start(); thread2.start(); } class MyThread extends Thread{ @Override public void run() { synchronized (object) { i++; System.out.println("i:"+i); try { System.out.println("线程"+Thread.currentThread().getName()+"进入睡眠状态"); Thread.currentThread().sleep(10000); } catch (InterruptedException e) { // TODO: handle exception } System.out.println("线程"+Thread.currentThread().getName()+"睡眠结束"); i++; System.out.println("i:"+i); } } } }
从上面输出结果能够看出,当Thread-0进入睡眠状态以后,Thread-1并无去执行具体的任务。只有当Thread-0执行完以后,此时Thread-0释放了对象锁,Thread-1才开始执行。测试
注意,若是调用了sleep方法,必须捕获InterruptedException异常或者将该异常向上层抛出。当线程睡眠时间满后,不必定会当即获得执行,由于此时可能CPU正在执行其余的任务。因此说调用sleep方法至关于让线程进入阻塞状态。this
调用yield方法会让当前线程交出CPU权限,让CPU去执行其余的线程。它跟sleep方法相似,一样不会释放锁。可是yield不能控制具体的交出CPU的时间,另外,yield方法只能让拥有相同优先级的线程有获取CPU执行时间的机会。spa
注意,调用yield方法并不会让线程进入阻塞状态,而是让线程重回就绪状态,它只须要等待从新获取CPU执行时间,这一点是和sleep方法不同的。
代码:操作系统
public class MyThread extends Thread{ @Override public void run() { long beginTime=System.currentTimeMillis(); int count=0; for (int i=0;i<50000000;i++){ count=count+(i+1); //Thread.yield(); } long endTime=System.currentTimeMillis(); System.out.println("用时:"+(endTime-beginTime)+" 毫秒!"); } } public class Run { public static void main(String[] args) { MyThread t= new MyThread(); t.start(); } } //用时:3 毫秒! //若是将 Thread.yield();的注释去掉,执行结果以下: 用时:16080 毫秒!
start()用来启动一个线程,当调用start方法后,系统才会开启一个新的线程来执行用户定义的子任务,在这个过程当中,会为相应的线程分配须要的资源。线程
run()方法是不须要用户来调用的,当经过start方法启动一个线程以后,当线程得到了CPU执行时间,便进入run方法体去执行具体的任务。注意,继承Thread类必须重写run方法,在run方法中定义具体要执行的任务。
getId()的做用是取得线程的惟一标识
public class Test { public static void main(String[] args) { Thread t= Thread.currentThread(); System.out.println(t.getName()+" "+t.getId()); } } //main 1
方法isAlive()的功能是判断当前线程是否处于活动状态
public class MyThread extends Thread{ @Override public void run() { System.out.println("run="+this.isAlive()); } } public class RunTest { public static void main(String[] args) throws InterruptedException { MyThread myThread=new MyThread(); System.out.println("begin =="+myThread.isAlive()); myThread.start(); System.out.println("end =="+myThread.isAlive()); } } //begin ==false //run=true //end ==false
方法isAlive()的做用是测试线程是否偶处于活动状态。什么是活动状态呢?活动状态就是线程已经启动且还没有终止。线程处于正在运行或准备开始运行的状态,就认为线程是“存活”的。
有个须要注意的地方
System.out.println("end =="+myThread.isAlive());
虽然上面的实例中打印的值是true,但此值是不肯定的。打印true值是由于myThread线程还未执行完毕,因此输出true。若是代码改为下面这样,加了个sleep休眠:
public static void main(String[] args) throws InterruptedException { MyThread myThread=new MyThread(); System.out.println("begin =="+myThread.isAlive()); myThread.start(); Thread.sleep(1000); System.out.println("end =="+myThread.isAlive()); }
则上述代码运行的结果输出为false,由于mythread对象已经在1秒以内执行完毕。
在不少状况下,主线程建立并启动了线程,若是子线程中药进行大量耗时运算,主线程每每将早于子线程结束以前结束。这时,若是主线程想等待子线程执行完成以后再结束,好比子线程处理一个数据,主线程要取得这个数据中的值,就要用到join()方法了。方法join()的做用是等待线程对象销毁。
public class Thread4 extends Thread{ public Thread4(String name) { super(name); } public void run() { for (int i = 0; i < 5; i++) { System.out.println(getName() + " " + i); } } public static void main(String[] args) throws InterruptedException { // 启动子进程 new Thread4("new thread").start(); for (int i = 0; i < 10; i++) { if (i == 5) { Thread4 th = new Thread4("joined thread"); th.start(); th.join(); } System.out.println(Thread.currentThread().getName() + " " + i); } } } /* main 0 main 1 main 2 main 3 main 4 new thread 0 new thread 1 new thread 2 new thread 3 new thread 4 joined thread 0 joined thread 1 joined thread 2 joined thread 3 joined thread 4 main 5 main 6 main 7 main 8 main 9 由上能够看出main主线程等待joined thread线程先执行完了才结束的。若是把th.join()这行注释掉,运行结果以下: main 0 main 1 main 2 main 3 main 4 main 5 main 6 main 7 main 8 main 9 new thread 0 new thread 1 new thread 2 new thread 3 new thread 4 joined thread 0 joined thread 1 joined thread 2 joined thread 3 joined thread 4 */
用来获得或者设置线程名称。
用来获取和设置线程优先级。此方法不经常使用,这种方式不可靠
用来设置线程是否成为守护线程和判断线程是不是守护线程。
守护线程和用户线程的区别在于:守护线程依赖于建立它的线程,而用户线程则不依赖。举个简单的例子:若是在main线程中建立了一个守护线程,当main方法运行完毕以后,守护线程也会随着消亡。而用户线程则不会,用户线程会一直运行直到其运行完毕。在JVM中,像垃圾收集器线程就是守护线程。
答:一个进程是一个独立(self contained)的运行环境,它能够被看做一个程序或者一个应用。而线程是在进程中执行的一个任务。线程是进程的子集,一个进程能够有不少线程,每条线程并行执行不一样的任务。不一样的进程使用不一样的内存空间,而全部的线程共享一片相同的内存空间。别把它和栈内存搞混,每一个线程都拥有单独的栈内存用来存储本地数据。
答:建立线程有两种方式:
1、继承 Thread 类,扩展线程。
2、实现 Runnable 接口。
答:启动一个线程是调用start()方法,使线程所表明的虚拟处理机处于可运行状态,这意味着它能够由JVM 调度并执行,这并不意味着线程就会当即运行。run()方法是线程启动后要进行回调(callback)的方法
答:sleep()方法(休眠)是线程类(Thread)的静态方法,调用此方法会让当前线程暂停执行指定的时间,将执行机会(CPU)让给其余线程,可是对象的锁依然保持,所以休眠时间结束后会自动恢复。wait()是Object类的方法,调用对象的wait()方法致使当前线程放弃对象的锁(线程暂停执行),进入对象的等待池(wait pool),只有调用对象的notify()方法(或notifyAll()方法)时才能唤醒等待池中的线程进入等锁池(lock pool),若是线程从新得到对象的锁就能够进入就绪状态。
答:
① sleep()方法给其余线程运行机会时不考虑线程的优先级,所以会给低优先级的线程以运行的机会;yield()方法只会给相同优先级或更高优先级的线程以运行的机会;
② 线程执行sleep()方法后转入阻塞(blocked)状态,而执行yield()方法后转入就绪(ready)状态;
③ sleep()方法声明抛出InterruptedException,而yield()方法没有声明任何异常;
④ sleep()方法比yield()方法(跟操做系统CPU调度相关)具备更好的可移植性。
小伙伴一块儿加油吧