当使用Thread线程时候,在线程内打印this.getName(线程名称)时,默认返回递增的Thread-i,就此产生了疑问,为何new Thread()对象,但是线程号确实递增的。
测试代码:
for(int i=0;i<10;i++){
Thread t = new Thread();
System.out.println(t.getName()); //名字自增
}
打印结果:
Thread-0
Thread-1
Thread-2
Thread-3
Thread-4
Thread-5
Thread-6
Thread-7
Thread-8
Thread-9
Thread源码部分:
//无参构造方法
public Thread(){
init(null, null, "Thread-" + nextThreadNum(), 0L);
}
//自增线程号
private static int threadInitNumber;
private static synchronized int nextThreadNum() {
return threadInitNumber++;
}
由此可见:Thread内部使用static修饰了线程号变量,并且在获取线程号方法上面加了锁,这样即使多线程同时访问,线程是安全的。即线程号是递增的。
总结
- 静态变量(static int number)
- 静态对象(static Object bean)
- 局部变量(int number)
- 局部对象(Object bean)
静态变量/对象:
被static修饰的成员变量和成员方法独立于该类的任何对象, 类的所有实例共享同一个static变量
静态变量也称为类变量,属于类对象所有,位于方法区,为所有对象共享,共享一份内存,一旦值被修改,则其他对象均对修改可见,故线程非安全。
局部变量/对象:
线程安全, 每个线程执行时都会把局部变量放在各自的帧栈的内存空间中,线程间不共享,故不存在线程安全问题。
对象如果是单例,也是线程不安全的。
- 静态变量
public class Thread2 extends Thread{
//static 静态常量
private static int threadInitNumber;
public Thread2(int i){
Thread2.threadInitNumber = i;
}
@Override
public void run() {
//打印静态变量
System.out.println("Thread-"+ threadInitNumber);
}
public static void main(String[] args) {
for(int i=0;i<10;i++){
Thread2 t = new Thread2(i);
t.start();
}
}
}
输出结果:静态变量被串改了,线程不安全
Thread-2
Thread-4
Thread-4
Thread-2
Thread-5
Thread-8
Thread-8
Thread-9
Thread-9
Thread-9
- 静态对象
public class Thread3 extends Thread{
//static 静态对象
private static Bean bean;
public Thread3(Bean bean){
Thread3.bean = bean;
}
@Override
public void run() {
System.out.println("Thread-"+ bean.getId()+"---"+bean);
}
public static void main(String[] args) {
for(int i=0;i<10;i++){
Bean bean = new Bean(i); //每次都初始化一个新的实体Bean
Thread3 t = new Thread3(bean);
t.start();
}
}
}
/**定义一个测试实体类*/
class Bean {
int id;
public Bean(int id){
this.id = id;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString() {
return "Bean [id=" + id + "]";
}
}
输出结果:对象Bean属性id也被串改了,线程不安全
Thread-2---Bean [id=2]
Thread-4---Bean [id=4]
Thread-3---Bean [id=3]
Thread-2---Bean [id=2]
Thread-6---Bean [id=6]
Thread-8---Bean [id=8]
Thread-8---Bean [id=8]
Thread-9---Bean [id=9]
Thread-9---Bean [id=9]
Thread-9---Bean [id=9]
- 局部变量:把static去掉
public class Thread4 extends Thread{
private int threadInitNumber;
private int nextThreadNum(){
int newNumber = threadInitNumber++;
return newNumber;
}
public void run(){
System.out.println("Thread-"+ nextThreadNum());
}
public static void main(String[] args) {
for(int i=0;i<10;i++){
Thread4 t = new Thread4();
t.start();
}
}
}
输出结果:变量没有被串改,都是从0开始的,线程安全
Thread-0
Thread-0
Thread-0
Thread-0
Thread-0
Thread-0
Thread-0
Thread-0
Thread-0
Thread-0
- 局部对象
public class Thread5 extends Thread{
private Bean bean;
public Thread5(Bean bean){
this.bean = bean;
}
public void run(){
System.out.println("Thread-"+ bean.getId()+"---"+bean);
}
public static void main(String[] args) {
for(int i=0;i<10;i++){
Bean bean = new Bean(i);
Thread5 t = new Thread5(bean);
t.start();
}
}
}
输出结果:对象私有,不共享,线程安全
Thread-0---Bean [id=0]
Thread-2---Bean [id=2]
Thread-1---Bean [id=1]
Thread-3---Bean [id=3]
Thread-4---Bean [id=4]
Thread-5---Bean [id=5]
Thread-6---Bean [id=6]
Thread-7---Bean [id=7]
Thread-9---Bean [id=9]
Thread-8---Bean [id=8]
网友评论