线程的终止与同步

发布于:2024-10-18 ⋅ 阅读:(14) ⋅ 点赞:(0)

线程终止

想要终止线程,可以在run方法内通过控制属性破坏继续执行的条件

public class MyRun implements Runnable {

	private volatile boolean flag = true;

	@Override
	public void run() {
		int i = 0;
		while (flag) {
			System.out.println("执行线程_" + i);
			i++;
		}
	}

	public void changeFlag() {
		flag = false;
	}
}

通过改变flag的值使线程停止运行。一定要给flag属性添加volatile关键字,保证其可见性。volatile就是让CPU每次操作这个数据时,必须立即同步到主内存,以及从主内存读取数据。

interrupt

    对于正在执行的线程,interrupt()可以给线程设置中断标志,但是无法中断线程的执行。默认有一个布尔类型的interrupted表示是否中断。当调用interrupt()就会修改interrupted的值为true。

    interrupted()可以获取中断标志(static修饰),返回一个布尔类型的值,同时修改interrupted为false。

    isInterrupted()也能获取中断标志,不会修改interrupted。

public class MyRun2 implements Runnable {

	@Override
	public void run() {
		int i = 0;
		
		while(!Thread.interrupted()){ //检查是否有中断状态
			System.out.println("我的线程_"+i);
			i++;
		}
		
	}

}
public class Test2 {

	public static void main(String[] args) {
		//System.out.println(Thread.interrupted());//默认为false
		
		MyRun2 mr = new MyRun2();
		Thread th = new Thread(mr);
		th.start();
		
		
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		th.interrupt(); //设置中断状态
		
	}
}

如果线程因为执行join(),sleep()或是wait()而进入了阻塞状态,此时要想停止它,可以让它调用interrupt(),程序会抛出InterruptedException异常而被catch()子句捕获,进行处理。

public class MyRun3 implements Runnable {

	@Override
	public void run() {
		int i = 0;
		while(true){
			System.out.println("线程_"+i);
			i++;
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				break;
			}
		}
	}

}

线程同步

    处理多线程的问题时,多个线程访问同一个对象,并且某些线程还想修改这个对象,这个时候我们就需要线程同步,线程同步其实就是一种等待机制,多个需要同时访问该对象的线程进入这个对象的等待池中,形成队列,等待前面线程使用完成,下一个线程再使用

    在Java语言中,引入对象互斥锁的概念,保证共享数据操作的完整性;

    每个对象都对应于一个可称为"互斥锁"的标记,这个标记保证在任一时刻,只能有一个线程访问对象;

    用关键字synchronized给对象加互斥锁.

 同步方法:

public synchronized 返回值类型 方法名(){

  

}

同步静态方法:

 public synchronized static void method1(){
 …
}

    当前线程调用本同步方法时,其他线程是不允许调用本对象中其他同步方法

    当前线程在调用本同步静态方法时,其他线程是不能够调用本类中的其他同步静态方法的,但是可以调用本类中的其他非同步方法或者非静态同步方法

     对于同步静态方法,此时锁定的是对应的类型(类名.class),所有属于该类型的对象,都在其锁定范围内,此时可以实现方法的同步调用

同步代码块:

public 返回值类型 方法名(){

    //代码1

    //代码2

    synchronized(对象){

        //代码3

    }  

}