目录
Thread的常见构造方法
Thread的常见属性
代码示例1
代码示例2
示例代码3
代码示例4
代码示例5
小结
线程中断
代码示例1
代码示例2
代码示例3
代码示例4
小结
线程等待
获取当前线程的引用
Thread的常见构造方法
举例
Thread t1 = new Thread();
Thread t2 = new Thread(new MyRunnable());
Thread t3 = new Thread("这是我的名字");
Thread t4 = new Thread(new MyRunnable(), "这是我的名字");
代码示例
public class Demo06 {
public static void main(String[] args) {
Thread t=new Thread(()->{
while(true){
System.out.println("hello thread");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
},"这是新线程");
t.start();
}
}
通过jconsole.exe观察
Thread的常见属性
属性 | 获取方法 |
ID | getId() |
名称 | getName() |
状态 | getState() |
优先级 | getPriority() |
是否后台进程 | isDaemon() |
是否存活 | isAlive() |
是否被中断 | isInterrupted() |
ID 是线程的唯一标识,不同线程不会重复;
名称是各种调试工具用到;
状态表示线程当前所处的一个情况;
优先级高的线程理论上来说更容易被调度到;
关于后台线程,记住一点:JVM会在一个进程的所有非后台线程结束后,才会结束运行;
是否存活,即简单的理解,为 run 方法是否运行结束了
代码示例1
public class Demo06 {
public static void main(String[] args) {
Thread t=new Thread(()->{
while(true){
System.out.println("hello thread");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
},"这是新线程");
System.out.println(t.getId());
System.out.println(t.getName());
System.out.println(t.getState());
System.out.println(t.getPriority());
System.out.println(t.isDaemon());
System.out.println(t.isAlive());
System.out.println(t.isInterrupted());
t.start();
}
}
运行结果
代码示例2
public class Demo07 {
public static void main(String[] args) throws InterruptedException {
Thread t=new Thread(()->{
System.out.println("线程开始");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("线程结束");
});
System.out.println(t.isAlive());
t.start();
System.out.println(t.isAlive());
Thread.sleep(3000);
System.out.println(t.isAlive());
}
}
运行结果
示例代码3
public class Demo08 {
private static boolean isQuit=false;
public static void main(String[] args) throws InterruptedException {
Thread t=new Thread(()->{
while(!isQuit){
System.out.println("线程工作中");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println("线程工作完毕!");
});
t.start();
Thread.sleep(5000);
isQuit=true;
System.out.println("设置 isQuit 为 true");
}
}
运行结果
代码示例4
public class Demo09 {
public static void main(String[] args) throws InterruptedException {
Thread t=new Thread(()->{
//Thread类内部有一个标志位,可以用来判定当前的循环是否要结束
while(!Thread.currentThread().isInterrupted()){
System.out.println("线程工作中");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
//throw new RuntimeException(e);
//1.假装没听见,循环继续正常执行
e.printStackTrace();
//2.加上一个bread,表示让线程立即结束
//break;
//3.做一些其它工作,完成之后再结束
break;
}
}
});
t.start();
Thread.sleep(5000);
System.out.println("让 t 线程终止");
t.interrupt();
}
}
运行结果
代码示例5
public class Demo10 {
public static void main(String[] args) throws InterruptedException {
Thread t=new Thread(()->{
for (int i = 0; i < 5; i++) {
System.out.println("t 线程工作中");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
});
t.start();
System.out.println("join 等待开始");
t.join();
System.out.println("join 等待结束");
}
}
小结
上面的代码是让主线程来等待 t 线程执行结束,一旦调用 join,主线程就会触发阻塞,此时 t 线程就可以趁机完成后续的工作,一直到阻塞到 t 执行完毕,join才会解除阻塞。
即:哪个线程调用 join(),哪个线程就会被阻塞。
代码示例6
public class Demo11 {
public static void main(String[] args) throws InterruptedException {
Thread t=new Thread(()->{
while(true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
});
System.out.println(t.getState());
t.start();
for (int i = 0; i < 5; i++) {
System.out.println(t.getState());
Thread.sleep(1000);
}
System.out.println(t.getState());
}
}
运行结果
线程中断
常见的两种方式:
1.通过共享的标记来进行沟通;
2.调用 interrupt() 方法来通知。
代码示例1
public class Demo11 {
private static class MyRunnable implements Runnable{
public volatile boolean isQuit=false;
@Override
public void run() {
while(!isQuit) {
System.out.println("开始");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println("结束");
}
}
public static void main(String[] args) throws InterruptedException {
MyRunnable target=new MyRunnable();
Thread t=new Thread(target);
t.start();
Thread.sleep(5000);
target.isQuit=true;
}
}
运行结果
代码示例2
public class Demo11 {
private static class MyRunnable implements Runnable{
@Override
public void run() {
while(!Thread.interrupted()) {
System.out.println("开始");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println("结束");
}
}
public static void main(String[] args) throws InterruptedException {
MyRunnable target=new MyRunnable();
Thread t=new Thread(target);
t.start();
Thread.sleep(5000);
t.interrupt();
}
}
运行结果
代码示例3
public class Demo11 {
private static class MyRunnable implements Runnable{
@Override
public void run() {
while(true){
System.out.println(Thread.currentThread().isInterrupted());
}
}
}
public static void main(String[] args) throws InterruptedException {
MyRunnable target=new MyRunnable();
Thread t=new Thread(target);
t.start();
Thread.sleep(2000);
t.interrupt();
}
}
运行结果
代码示例4
public class Demo11 {
private static class MyRunnable implements Runnable{
@Override
public void run() {
while(true){
System.out.println(Thread.interrupted());
}
}
}
public static void main(String[] args) throws InterruptedException {
MyRunnable target=new MyRunnable();
Thread t=new Thread(target);
t.start();
Thread.sleep(2000);
t.interrupt();
}
}
运行结果
小结
如果线程因为调用wait/join/sleep等方法而阻塞挂起,则以InterruptedException异常的形式通知,清除中断标志,当出现InterruptedException的时候,要不要结束线程取决于catch中代码的写法,可以选择忽略这个异常,也可以选择跳出循环结束线程;
1.Thread.interrupted()判断当前线程的中断标志被设置,清除中断标志;
2.Thread.currentThread().isInterrupted()判断指定线程的中断标志被设置,不清楚中断标志;
这两种方法通知收到的更及时,及时线程正在sleep也可以马上收到。
线程等待
获取当前线程的引用
方法 | 属性 |
public static Thread currentThread() | 返回当前线程对象的引用 |
public class ThreadDemo {
public static void main(String[] args) {
Thread thread = Thread.currentThread();
System.out.println(thread.getName());
}
}