线程终止
想要终止线程,可以在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
}
}