Java并发编程——基本方法详解

start() 与 run()

说明

start() 方法用于启动线程,当一个线程调用 start() 方法,则意味着该线程进入就绪状态,等待线程调度

run() 方法只是 Thread 类的一个普通方法,其中保存着该线程需要完成的工作】

区别

start() 方法是真正意义上启动一个线程,参与线程调度,而调用 run() 方法并没有启动一个新的线程,如果在主线程中调用一个线程的 run() 方法,则 run() 方法的内容仍然是主线程执行


sleep()

说明

sleep() 方法会让当前线程从 Running 状态进入 Timed Waiting 状态

需要注意的是,sleep() 作为 Thread 类的一个静态方法,与谁调用他无关,只会将当前线程睡眠

import lombok.SneakyThrows;

public class SleepAndYield {
	public static void main(String[] args) throws InterruptedException {
		Thread t = new Thread() {
			@SneakyThrows
			@Override
			public void run() {
				for(int i = 0; i < 9999999; i ++) {
					System.out.println(i);
				}
			}
		};
		t.start();
		t.sleep(5000);
	}
}

在主线程中,通过 t.sleep() 的方式希望让子线程进入睡眠,但并不会起作用,这里的 t.sleep() 相当于 Thread.sleep() ,恰恰是让主线程睡眠,故一般在使用 sleep() 时,也是用 Thread.sleep() 的形式

在其它线程中,可以通过 interrupt() 方法打断睡眠,原睡眠线程抛出 InterruptedException

public class SleepAndYield {
	public static void main(String[] args) throws InterruptedException {
		Thread t = new Thread() {
			@Override
			public void run() {
				System.out.println("enter sleep");
				try {
					Thread.sleep(10000);
				} catch (InterruptedException e) {
					System.out.println("interrupt success");
					e.printStackTrace();
				}
			}
		};
		t.start();
		Thread.sleep(1000);
		System.out.println("interrupt");
		t.interrupt();
	}
}

抛出异常后,被 catch 捕获,进行处理

通过 TimeUnit 增强 sleep 的可读性

通过 TimeUnit 实现线程睡眠,效果与 Thread.sleep() 完全一致,但大大增强了可读性

TimeUnit.DAYS.sleep(1);            //天
TimeUnit.HOURS.sleep(1);           //小时
TimeUnit.MINUTES.sleep(1);         //分
TimeUnit.SECONDS.sleep(1);         //秒
TimeUnit.MILLISECONDS.sleep(1);    //毫秒
TimeUnit.MICROSECONDS.sleep(1);    //微秒
TimeUnit.NANOSECONDS.sleep(1);     //纳秒

yield()

yield() 方法会让当前线程从 运行状态 进入 可运行状态,与 sleep() 不同,yield() 并非让线程阻塞等待,而是让出当前占用的 CPU 时间片,但在下一次线程调度中仍然有机会占用时间片

与 sleep() 相似,也是使用 Thread.yield() 调用


getPriority() 与 setPriority()

getPriority() 用于获取线程优先级,setPriority() 用于设置线程优先级,与 sleep() 和 yield() 不同,这两个方法都用线程对象调用

优先级使用 1 ~ 10 的整数表示,默认优先级为 5 ,优先级越高,在线程调度时被分配到 CPU 时间片的概率更大


join()

join() 方法用于等待指定线程运行结束,可传入参数表示最多等待时间,如 join(1000) 表示最多等待1000毫秒,若 1000 毫秒后线程未运行结束,则停止等待,若在 1000 毫秒内线程已经结束,如线程运行只需要 500 毫秒,那么也会停止等待,而不是继续等待直到 1000毫秒,特殊的是,join(0) 与 join() 等价,该方法同样也通过线程对象调用

import lombok.SneakyThrows;

public class JoinTest {
	static int value = 0;
	public static void main(String[] args) throws InterruptedException {
		System.out.println("开始");
		Thread t = new Thread() {
			@SneakyThrows
			@Override
			public void run() {
				System.out.println("start");
				sleep(1000);
				value = 10;
				System.out.println("end");
			}
		};
		t.start();;
		t.join();
		System.out.println("结果为:" + value);
		System.out.println("结束");
	}
}

该示例中,主线程中通过 t.join() ,等待 t 线程执行结束,再输出被线程 t 修改过的 value


interrupt() 、isInterrupted() 与 interrupted()

对于 interrupt() ,用于线程的打断

  • 打断 sleep 、wait 、join 中的线程,打断后抛出 InterruptedException ,且中断标记被 JVM 清除,也就是调用 isInterrupted() 结果为 false
  • 打断正常运行的线程,仅仅是将线程的中断标记位置为 true ,也就是调用 isInterrupted() 结果为 true ,并不会停止线程。需要用户自己去监视线程的中断标记位并做处理
public class InterruptTest {
	public static void main(String[] args) throws InterruptedException {
		Thread t = new Thread() {
			@Override
			public void run() {
				while (true) {
					boolean interrupted = Thread.currentThread().isInterrupted();
					if(interrupted) {
						System.out.println("break");
						break;
					}
				}
			}
		};
		t.start();
		Thread.sleep(100);
		System.out.println("interrupt");
		t.interrupt();
	}
}

该示例在主线程中打断 t 线程,t 线程监视中断标记,一旦为 true ,表示收到打断信号,跳出循环

对于 isInterrupted() 与 interrupted() ,用于检测线程是否被打断

  • isInterrupted() 用于检测线程是否被打断,返回中断标记位,使用线程对象调用
  • interrupted() 用于检测当前线程是否被打断,返回并清除中断标记位,它是静态方法,通过 Thread 类名调用

废弃方法

  • stop() 用于终止线程
  • suspend() 用于挂起(暂停)线程
  • resume() 用于恢复线程运行

Guess you like

Origin blog.csdn.net/qq_25274377/article/details/120587324