您的位置  > 互联网

Java面试题:线程类中的实例变量

例子:

public class MYThread extends Thread {
	private int count = 5;
	public MYThread(String name) {
		super();
		this.setName(name);//设置线程的名字
	}
	@Override
	public void run() {
		super.run();
		while (count > 0) {
			count -- ;
			System.out.println("由 "+this.currentThread().getName()+" 计算,count= "+count);
		}
	}
}

public class TetsMYThread {
	public static void main(String[] args) {
		MYThread t1 = new MYThread("A");
		MYThread t2 = new MYThread("B");
		MYThread t3 = new MYThread("C");
		t1.start();
		t2.start();
		t3.start();
	}
}

上面创建了三个线程。 每个线程都有自己的计数变量,并减少自己变量的计数值。 在这种情况下,变量不是共享的,多个线程不会访问同一个实例变量。

改进后的代码:

public static void main(String[] args) {
		MYThread t = new MYThread();
		Thread t1 = new Thread(t,"A");
		Thread t2 = new Thread(t,"B");
		Thread t3 = new Thread(t,"C");
		Thread t4 = new Thread(t,"D");
		Thread t5 = new Thread(t,"E");
		t1.start();
		t2.start();
		t3.start();
		t4.start();
		t5.start();
	}

public class MYThread extends Thread {
	private int count = 5;
	@Override
	public void run() {
		super.run();
		count--;
		System.out.println("由 " + this.currentThread().getName()
				+ " 计算,count= " + count);
	}
}

AC 两个线程同时打印的count值为3,说明两个线程同时处理count,导致“非线程安全问题”。 我们想要打印的是结果不是重复的,而是按顺序减少的。

在一些JVM中,i--操作分为3步:

1.取出原来的i值

2. 计算i-1

3. 给i赋值

这三个步骤中,如果多个线程同时访问的话,肯定会出现非线程安全问题。

再次改进代码:

public class MYThread extends Thread {
	private int count = 5;
	@Override
	synchronized public void run() {
		super.run();
		count--;
		System.out.println("由 " + this.currentThread().getName()
				+ " 计算,count= " + count);
	}
}

在run方法中添加关键字,这样当多个线程执行run方法时,就会在队列中进行处理。 线程在调用run方法之前,首先判断run方法是否被锁定。 如果被锁定,说明其他线程正在调用run方法,则必须等待其他线程完成对run方法的调用,然后才能执行run方法。 这样就达到了对调用进行排队的目的,同时也实现了按顺序计数- -,并且可以锁定任何对象和方法。 枷锁的代码称为“互斥区”或“临界区”。

再次了解

当一个线程想要执行同步方法中的代码时,该线程首先尝试获取锁。 如果能拿到,那么线程就可以执行里面的代码了。 如果它无法获取它,那么线程将继续尝试获取它。 拿着这把锁直到你得到它。 请注意,多个线程同时竞争此锁。 。 。