有关 thread.stop()方法的使用,先看以下代码
package com.luo.con_2_2_2;
public class StopThreadUnsafe {
public static User u = new User();
public static class User{
private int id;
private String name;
public User() {
id = 0;
name = "0";
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public static class ChangeObjectThread extends Thread {
@Override
public void run(){
while (true) {
synchronized (u) {
int v = (int) (System.currentTimeMillis()/1000);
u.setId(v);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
u.setName(String.valueOf(v));
}
Thread.yield();
}
}
}
public static class ReadObjectThread extends Thread {
@Override
public void run() {
while (true) {
synchronized (u) {
if (u.getId() != Integer.parseInt(u.getName())) {
System.out.println(u.toString());
}
}
Thread.yield();
}
}
}
public static void main(String[] args) throws InterruptedException {
new ReadObjectThread().start();
while (true) {
Thread t = new ChangeObjectThread();
t.start();
Thread.sleep(150);
t.stop();
}
}
}
执行后会发现出现id 不等于 name 的情况
User{id=1688181135, name='1688181134'}
User{id=1688181135, name='1688181134'}
User{id=1688181135, name='1688181134'}
User{id=1688181135, name='1688181134'}
User{id=1688181135, name='1688181134'}
User{id=1688181135, name='1688181134'}
User{id=1688181135, name='1688181134'}
原因是
使用Thread.stop()
方法:在main
方法的循环中,使用了Thread.stop()
方法来停止ChangeObjectThread
线程。然而,Thread.stop()
是一个不安全的方法,它会立即终止线程,可能导致线程被终止时处于不一致的状态。因此,应该避免使用Thread.stop()
。
优化方案:
使用了、volatile
关键字来保证线程安全地停止ChangeObjectThread
。同时,通过synchronized
关键字对共享变量u
进行同步,确保正确的读写操作。
package com.luo.con_2_2_2;
public class StopThreadSafe {
public static User u = new User();
public static class User {
private int id;
private String name;
public User() {
id = 0;
name = "0";
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
public synchronized int getId() {
return id;
}
public synchronized void setId(int id) {
this.id = id;
}
public synchronized String getName() {
return name;
}
public synchronized void setName(String name) {
this.name = name;
}
}
public static class ChangeObjectThread extends Thread {
private volatile boolean isRunning = true;
public void stopRunning() {
isRunning = false;
}
@Override
public void run() {
while (isRunning) {
synchronized (u) {
int v = (int) (System.currentTimeMillis() / 1000);
u.setId(v);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
u.setName(String.valueOf(v));
}
}
}
}
public static class ReadObjectThread extends Thread {
@Override
public void run() {
while (true) {
synchronized (u) {
if (u.getId() != Integer.parseInt(u.getName())) {
System.out.println(u.toString());
}
}
}
}
}
public static void main(String[] args) throws InterruptedException {
new ReadObjectThread().start();
while (true) {
ChangeObjectThread t = new ChangeObjectThread();
t.start();
Thread.sleep(150);
t.stopRunning();
}
}
}