Java笔记-多线程之线程控制

线程控制

我们已经知道了线程的调度,接下来我们就可以使用如下方法对象线程进行控制。


1.线程休眠

public static void sleep(long millis):让当前线程处于暂停状态,millis参数毫秒值,即暂停时间。

代码演示如下:

1.MyThread.java:

public class MyThread extends Thread {
	public MyThread() {
	}

	public MyThread(String name) {
		super(name);
	}

	@Override
	public void run() {
		for (int i = 0; i < 20; i++) {
			try {
				// 线程休眠 1000ms 即 1s
				sleep(1000);
				System.out.println("我是---->" + getName() + ":" + i);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

2.Test.java:

public class Test {
	public static void main(String[] args) {
		MyThread t1 = new MyThread("张飞");
		MyThread t2 = new MyThread("关羽");
		t1.start();
		t2.start();
	}
}

线程加入(线程强制执行)

public final void join():后面其他线程等待,当前线程执行完,后面其他线程再开始执行。

调用必须是在当前线程start以后,其他线程start之前。

代码演示如下:

1.MyThread.java:

public class MyThread extends Thread {
	public MyThread() {
	}

	public MyThread(String name) {
		super(name);
	}

	@Override
	public void run() {
		for (int i = 0; i < 20; i++) {
			try {
				// 线程休眠 100ms
				sleep(100);
				System.out.println("我是---->" + getName() + ":" + i);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

2.Test.java:

public class Test {
	public static void main(String[] args) throws InterruptedException {
		MyThread t0 = new MyThread("刘备");
		MyThread t1 = new MyThread("张飞");
		MyThread t2 = new MyThread("关羽");
		t0.start();
		// 线程加入 线程强制执行 
		// 运行结果 刘备先买完,然后张飞关羽再多线程买
		t0.join();
		t1.start();
		t2.start();
		//如果这样
		/*
		t1.start();
		t0.start();
		// 线程加入 线程强制执行 
		// 运行结果 刘备张飞多线程买,都买完之后,关羽再买
		t0.join();
		t2.start();
		*/
	}
}

3.线程礼让

public static void yield():当前执行的线程,执行完毕后会礼让后面的线程。也就是说最好的情况就是每个线程都交替执行,没有连续多次执行同一个线程的情况发生。

但是由于线程执行具有随机性,所以该方法并不能保证完全的交替执行,所以说效果并不好,用处较少。

演示代码如下:

1.MyThread.java:

public class MyThread extends Thread {
	public MyThread() {
	}

	public MyThread(String name) {
		super(name);
	}

	@Override
	public void run() {
		// 线程礼让
		Thread.yield();
		for (int i = 0; i < 20; i++) {
			try {
				// 线程休眠 100ms
				sleep(100);
				System.out.println("我是---->" + getName() + ":" + i);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

2.Test.java:

public class Test {
	public static void main(String[] args) throws InterruptedException {
		MyThread t1 = new MyThread("张飞");
		MyThread t2 = new MyThread("关羽");
		t1.start();
		t2.start();
	}
}

4.后台线程(守护线程)

public final void setDaemon(boolean on):被守护线程如果执行结束,则守护线程直接终止,不继续执行任何一行代码。

注意:守护线程要在声明后,和start()前声明。否则报错!


演示代码如下:

刘关张三兄弟,一起上阵杀敌。
目的:一旦刘备(主公)死了,关羽张飞就不再杀敌直接被俘虏了。

1.MyThread.java:

public class MyThread extends Thread {
	public MyThread() {
	}

	public MyThread(String name) {
		super(name);
	}

	@Override
	public void run() {
		System.out.println(getName() + "--->已经到达战场!");
		// 线程礼让
		Thread.yield();
		for (int i = 0; i < 20; i++) {
			try {
				// 线程休眠 100ms
				sleep(100);
				System.out.println(getName() + "开始对抗第 " + i + " 个敌人");
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		System.out.println(getName() + "--->战死了!!!!");
	}
}

2.Test.java:

public class Test {
	public static void main(String[] args) throws InterruptedException {
		MyThread t1 = new MyThread("张飞");
		MyThread t2 = new MyThread("关羽");
		// 设置后台线程 守护线程
		t1.setDaemon(true);
		t2.setDaemon(true);
		t1.start();
		t2.start();
		System.out.println("刘备----->到达战场!!!!");
		for (int i = 0; i < 10; i++) {
			// 为了明显让主线程也休眠
			Thread.sleep(100);
			System.out.println("刘备开始对抗第 " + i + " 个敌人");
		}
		System.out.println("刘备战死了!!!!");
	}
}

5.中断线程

例子:刘关张三兄弟都困了,刘备先挺不住睡觉了,关羽张飞看到就也睡觉了,但是刘备先醒了,看到他们两个在睡觉,就把他们两个叫醒了。

public final void stop():不推荐使用,此方法太血腥。直接中断线程,后面代码不执行了。
例子中,就是刘备醒了后看到两兄弟在睡觉,很生气,叫人把他们弄死了。两兄弟再也睡不醒了。

public void interrupt():不推荐使用,此方法太暴力,直接给当前线程抛出了一个异常。
Interrupt()方法会向子线程抛出一个InterruptedException异常,异常结束了子线程的休眠。

推荐使用的方法:
像停止一个高速旋转的轮子一样,慢慢停止旋转。
代码:一般子线程里面都是长循环或耗时操作,只要把长循环或耗时操作的状态改为不再循环,则慢慢停止。
推荐使用:布尔值,控制循环停止,温和终止方式。

演示代码如下:

1.MyThread.java:

public class MyThread extends Thread {
	public MyThread() {
	}

	public MyThread(String name) {
		super(name);
	}

	@Override
	public void run() {
		System.out.println(getName() + "--->开始睡觉!!!");
		try {
			for (int i = 0; i < 10 && Flag.FLAG; i++) {
				// 线程休眠 1000ms
				sleep(1000);
				System.out.println(getName() + "--->正在睡觉--" + i);
			}
		} catch (InterruptedException e) {
			System.out.println(getName() + "--->被一棒子打醒!");
		}
		System.out.println(getName() + "--->睡醒了!!!");
	}
}

2.Flag.java:

public class Flag {
	//仅仅用来判断循环是否继续
	public static boolean FLAG = true;
}

3.Test.java:

public class Test {
	public static void main(String[] args) throws InterruptedException {
		MyThread t1 = new MyThread("张飞");
		MyThread t2 = new MyThread("关羽");
		t1.start();
		t2.start();
		System.out.println("刘备----->开始睡觉!!!!");
		// 为了明显让主线程也休眠
		Thread.sleep(3000);
		System.out.println("刘备睡醒了!!!!");
		// 使用boolean值控制循环停止,温和
		// 刘备睡醒后二人也能再睡短短的一会儿,然后被温柔的叫醒
		Flag.FLAG = false;
		// 太暴力,一棒子打醒了二人
		// t1.interrupt();
		// t2.interrupt();
		// 太血腥,直接弄死了二人,再也睡不醒了
		// t1.stop();
		// t2.stop();
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值