接下来介绍线程安全及共享变量
public class MyThreadVariableAndSafe extends Thread {
private int count = 5;
public MyThreadVariableAndSafe(String name) {
super();
this.setName(name);
}
@Override
public void run() {
super.run();
while (count > 0) {
count--;
System.out.println("由 " + this.getName() + " 计算,count=" + count);
}
}
public static void main(String[] args) {
MyThreadVariableAndSafe a = new MyThreadVariableAndSafe("A");
MyThreadVariableAndSafe b = new MyThreadVariableAndSafe("B");
MyThreadVariableAndSafe c = new MyThreadVariableAndSafe("C");
a.start();
b.start();
c.start();
}
}
通过运行上面代码不难看出变量是不共享的因为每个线程都会打印count至0,为什么呢?因为count是实例变量,在这里的main方法中是实例化三个类去运行,所以每个实例类都有自己的count变量,一个很直接的想法就是把count直接变为静态变量,也就是
public static int count = 5;
运行后也不难看出确实是不是每个线程都去打印count变量了,但是确引起另一个问题,我们期望的答案是4,3,2,1,可是结果却有可能是3,2,3,0,1这里显然出现了线程安全问题,因为线程的执行时交替的,并不是按顺序,可能A线程读取到变量的同时,B线程也读取到了该值,所以他们对count分别做出了修改,解决该问题的代码如下:
//线程安全的类
class MyThreadVariableAndSafeSultion extends Thread {
private int a = 5;
@Override
synchronized public void run() {
super.run();
a = a-1;
System.out.println("由 " + this.getName() + " 计算,a=" + a);
}
public static void main(String[] args) {
MyThreadVariableAndSafeSultion m = new MyThreadVariableAndSafeSultion();
Thread d = new Thread(m, "D");
Thread e = new Thread(m, "E");
Thread f = new Thread(m, "f");
Thread h = new Thread(m, "H");
Thread g = new Thread(m, "G");
d.start();
e.start();
f.start();
h.start();
g.start();
}
}
非线程安全:是指多个线程对同一个对象中的同一个实例变量进行操作时会出现值被更改、值不同步的情况,进而影响程序的执行流程
大多数停止一个线程的操作使用Thread.interrupt(),但是这个方法实际上不会终止一个正在运行的线程,还需要加入一个判断才可以完成线程的停止,在java中有三种方法可以终止正在运行的线程
- 使用退出标志,使线程正常退出,也就是当run方法完成后线程终止
- 使用stop方法强行终止线程,但是不推荐,这个和suspend、resume一样都是过期废弃的,使用会产生不可预料的后果
- 使用interrupt方法中断线程
值得注意是在sleep的线程如果被中断会报错