终止线程
如果我们想在一个线程中终止另一个线程我们一般不使用 JDK 提供的 stop()/destroy() 方法(它们本身也被 JDK 废弃了)。通常的做法是提供一个 boolean 型的终止变量,当这个 变量值为 false时,则终止线程的运行。
import java.io.IOException;
public class StopThreadTest implements Runnable{
private boolean flag=true;
/**
* 线程体方法
*/
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"线程开始");
int i=0;
while(flag){
System.out.println(Thread.currentThread().getName()+" "+i++);
try{
Thread.sleep(1000);
}catch(Exception e){
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+"线程结束");
}
public void stop(){
this.flag=false;
}
public static void main(String[] args) {
System.out.println("主线程开始");
StopThreadTest stopThreadTest=new StopThreadTest();
Thread t1=new Thread(stopThreadTest);
t1.start();
try {
System.in.read();
} catch (IOException e) {
e.printStackTrace();
}
stopThreadTest.stop();
System.out.println("主线程结束");
}
}
暂停当前线程执行sleep/yield
暂停线程执行常用的方法有 sleep()和 yield()方法,这两个方法的区别是:
sleep()方法:可以让正在运行的线程进入阻塞状态,直到休眠时间满了,进入就绪状 态。
看上面的例子
yield()方法:
可以让正在运行的线程直接进入就绪状态,让出 CPU 的使用权。
yield()方法的作用:暂停当前正在执行的线程,并执行其他线程。 <br />yield()让当前正在运行的线程回到可运行状态,以允许具有相同优先级的其他线程获得运行的机会。因此,使用 yield()的目的是让具有相同优先级的线程之间能够适当的轮换执行。 但是,实际中无法保证 yield()达到让步的目的,因为,让步的线程可能被线程调度程序再次选中 <br />使用 yield 方法时要注意的几点:
- yield 是一个静态的方法。
- 调用 yield 后,yield 告诉当前线程把运行机会交给具有相同优先级的线程。
- yield 不能保证,当前线程迅速从运行状态切换到就绪状态
- yield 只能是将当前线程从运行状态转换到就绪状态,而不能是等待或者阻塞状态。
public class YieldThreadDemo implements Runnable{
@Override
public void run() {
for(int i=0;i<10;i++){
if("Thread-0".equals(Thread.currentThread().getName())){
if(i==0){
Thread.yield(); //这里可以看出,yieal是个静态方法,直接类调用
}
}
System.out.println(Thread.currentThread().getName()+" "+i);
}
}
public static void main(String[] args) {
Thread t1=new Thread(new YieldThreadDemo());
Thread t2=new Thread(new YieldThreadDemo());
t1.start();
t2.start();
}
}
线程的联合
当前线程邀请调用方法的线程优先执行,在调用方法的线程执行结束之前,当前线程不 能再次执行。线程 A 在运行期间,可以调用线程 B 的 join()方法,让线程 B 和线程 A 联合。 这样,线程 A 就必须等待线程 B 执行完毕后,才能继续执行
join方法的使用
join()方法就是指调用该方法的线程在执行完 run()方法后,再执行 join 方法后面的代码, 即将两个线程合并,用于实现同步控制
public class JoinThreadDemo {
public static void main(String[] args) {
Thread threadA=new Thread(new A());
Thread threadB=new Thread(new B());
threadA.start();
threadB.start();
for(int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName()+" "+i);
if(i==2){
try {
threadA.join(); //想要联合谁,就用对方对象调用join()方法,相当于对方加入进来
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class A implements Runnable{
@Override
public void run() {
for(int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName()+" "+i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class B implements Runnable{
@Override
public void run() {
for(int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName()+" "+i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
线程联合案例
public class JoinDemo2 {
public static void main(String[] args) {
System.out.println("女朋友让男朋友买奶茶的故事");
Thread girlThread=new Thread(new Girl());
girlThread.start();
}
}
class Girl implements Runnable{
@Override
public void run() {
System.out.println("女朋友想喝奶茶");
System.out.println("女朋友让男朋友去买一杯沽名");
Thread boyThread=new Thread(new Boy());
boyThread.start();
System.out.println("等待男朋友带奶茶回来");
try {
boyThread.join();
} catch (InterruptedException e) {
System.out.println("时间太长,打电话催一下");
e.printStackTrace();
}
System.out.println("男朋友带奶茶回来了,给她一个吻");
}
}
class Boy implements Runnable{
@Override
public void run() {
System.out.println("男朋友出门买奶茶");
System.out.println("男朋友买奶茶要10分钟");
for(int i=0;i<10;i++){
System.out.println("第"+i+"分钟");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("男朋友买奶茶回来了");
}
}
Thread类中的其他常用方法
获取当前线程名称
public class GetName_1 extends Thread{
@Override
public void run() {
System.out.println(this.getName());
}
}
class GetName_2 implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}
设置线程名称
class SetName_1 extends Thread{
public SetName_1(String name){
super(name);
}
@Override
public void run() {
System.out.println(this.getName());
}
}
public class SetName {
public static void main(String[] args) {
SetName_1 setName_1=new SetName_1("耿");
setName_1.start();
}
}
class SetName_2 implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}
public class SetNameDemo_2 {
public static void main(String[] args) {
Thread thread=new Thread(new SetName_2());
thread.setName("龙");
thread.start();
}
}
判断当前线程是否存活
isAlive()方法: 判断当前的线程是否处于活动状态。
活动状态是指线程已经启动且尚未终止,线程处于正在运行或准备开始运行的状态,就 认为线程是存活的
public class AliveDemo {
public static void main(String[] args) {
Thread aliveThread=new Thread(new Alive());
System.out.println(aliveThread.isAlive()+"2");
aliveThread.start();
System.out.println(aliveThread.isAlive()+"3");
try{
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(aliveThread.isAlive()+"4");
}
}
class Alive implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().isAlive()+"1");
try{
Thread.sleep(20000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}