进程是受操作系统管理的基本运行单元
线程是在进程中独立运行的子任务
1. currentThread()
方法
返回代码正在被哪个线程调用的信息
测试1
public MyThread extends Thread {
public MyThread() {
Thread.currentThread().getName();
}
@Override
public void run() {
Thread.currentThread().getName();
}
}
········································································
public class RunTest {
public static void main(String[] args) {
MyThread mythread = new MyThread(); //main
mythread.start(); //Thread-0
mythread.run(); //main
}
}
2. isAlive() 方法
判断当前线程是否处于活动状态
测试2
public class CountOperate extends Thread {
public CountOperate () {
System.out.println("1:" + Thread.currentThread().getName());
System.out.println("1:" + Thread.currentThread().isAlive());
System.out.println("1:" + this.getName());
System.out.println("1:" + this.isAlive());
}
@Override
public void run() {
System.out.println("2:" + Thread.currentThread().getName());
System.out.println("2:" + Thread.currentThread().isAlive());
System.out.println("2:" + this.getName());
System.out.println("2:" + this.isAlive());
}
}
········································································
public class RunTest {
public static void main(String[] args) {
CountOperate c = new CountOperate();
Thread t1 = new Thread(c);
t1.setName("A");
t1.start();
}
}
//1:main
//1:true
//1:Thread-0
//1:false
//2:A
//2:true
//2:Thread-0
//2:false
造成这种差异的原因来自于Thread.currentThread()和this的差异
3. sleep()
方法
作用是在指定的毫秒数内让当前正在执行的线程(Thread.currentThread()返回的线程)休眠
4. getId()
方法
取得线程的唯一标识
public class RunTest {
public static void main(String[] args) {
Thread.currentThread().getName(); //main
Thread.currentThread().getId(); //1
}
}
5. interrupt()
方法、interrupted()
方法、isInterrupted()
方法
public void interrupt(){}
public boolean isInterrupted(){}
public static boolean interrupted(){}
interrupt()
方法 在当前线程中打一个中断状态标记
interrupted()
方法 测试当前线程是否已中断,并清除中断状态标记为false
isInterrupted()
方法 测试当前线程是否已中断,不清除标记
线程在sleep()状态下调用interrupt()停止,会抛出InterruptedException异常,并清除停止状态值,使之变成false
先调用interrupt()停止再调用sleep()方法,也会抛出InterruptedException异常
方法stop()已经被作废,因为如果强制让线程停止则有可能使一些请理性的工作得不到完成。另外一个情况就是对锁定的对象进行了解锁,导致数据的不到同步的处理,出现数据不一致的问题
6. yield()
方法
作用是放弃当前的CPU资源,将它让给其他的任务去占用CPU执行时间。但放弃的时间不确定,有可能刚放弃,马上又获得CPU时间片
public static native void yield();
suspend()和resume()方法分别是暂停线程和恢复线程运行,但它们有缺点:
- 暂停后不会释放持有锁,使得其他线程无法获得该锁
- 也会出现和stop()同样的数据不同步问题
7. setPriority()
方法
设置线程的优先级
在Java中,线程优先级分为1~10,大于10或小于1会抛出IllegalArgumentException异常
JDK中使用3个常量来预置定义优先级的值:
public final static int MIN_PRIORITY = 1;
public final static int NORM_PRIORITY = 5;
public final static int MAX_PRIORITY = 10;
getPriority()
方法查询线程优先级
线程的优先级具有继承性
比如A线程启动B线程,则B线程和A线程的优先级是一样的
8. setDaemon()
方法
public final void setDaemon(boolean on)
在Java中,有两种线程,一种是用户线程,一种是守护线程
典型的守护线程就是垃圾回收线程
只要当前JVM实例中存在非守护线程且没有结束,守护线程就要工作
class DaemonRun extends Thread {
private int i = 0;
public int getI() {
return i;
}
@Override
public void run() {
try {
while(true) {
i++;
System.out.println("i=" + i);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws InterruptedException {
DaemonRun daemonRun = new DaemonRun();
daemonRun.setDaemon(true);
daemonRun.start();
Thread.sleep(3000);
System.out.println("停止了");
}
//i=1
//i=2
//i=3
//停止了
println方法内部是同步的
public void println(String x) {
synchronized (this) {
print(x);
newLine();
}
}