我在接受采访时被问到一个问题。
问题如下所述:
有一个类1.8.2
,其中有一个名为Employee
的方法。
我们将此课程的三个对象说成getDetail()
,e1
和e2
并将其传递给三个不同的帖子e3
,t1
和t2
。
现在开始线程。
我们如何限制线程访问t3
方法,以便一次只有一个线程可以访问该方法。
我的意思是说如果getDetail
位于t1
方法内,则其他任何线程都无法访问getDetail
类的getDetail
方法。
提前感谢您的帮助。
答案 0 :(得分:3)
您可以将方法标记为synchronized
,如此
class Employee {
synchronized Detail getDetail() { ... }
}
然而,在您描述的情况下,不需要同步,因为每个线程都有自己的Employee
实例。但是如果实例将在线程之间共享,或者Employee
类具有static
变量或类共享其中的一些数据,则需要它。
即使每个线程都有自己的实例,这也可能导致问题。
在最后一种情况下,如果方法返回一些复杂对象,也可能会出现问题,让我们将其称为EmployeeDetail
。当您调用getDetail()
时,您将收到对EmployeeDetail
对象的引用,该对象可能不是线程安全的。因此,您需要使整个EmployeeDetail
类线程安全。
如果您需要其他方法,例如setDetail(EmployeeDetail)
,则可以标记synchronized
,这将正确设置EmployeeDetail
引用。
答案 1 :(得分:0)
根据我的理解,我认为使线程限制getDetails
方法是没有意义的,假设它是对象级方法。因为每个线程都有一个不同的对象。交叉没有变化。
getDetails()
的内容,而这只是返回值。更好地限制对更改对象属性的方法的访问。
import java.util.ArrayList;
public class Threading {
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
Employee e1 = new Employee("e1");
ArrayList<Employee> emps = new ArrayList<Employee>();
emps.add(e1);
ThreadEmployee t = new ThreadEmployee(emps);
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
t1.setName("t1");
t2.setName("t2");
t1.start(); t2.start();
t1.join(); t2.join();
for(Employee e: emps)
{
System.out.println(e.getDetail());
}
}
}
class ThreadEmployee implements Runnable {
private ArrayList<Employee> emps;
ThreadEmployee(ArrayList<Employee> emps) {
this.emps = emps;
}
public void run() {
// TODO Auto-generated method stub
for(Employee e: emps)
{
e.changeDetail(e.getDetail() + "-" + Thread.currentThread().getName());
}
}
}
class Employee {
private String name;
Employee() {
}
Employee(String name) {
this.name = name;
}
public String getDetail() {
return name;
}
synchronized public void changeDetail(String name) {
this.name = name;
}
}
即使我不知道线程实际上如何执行它完全掌握在JVM手中,但最后我可以确定只有一个对象一次访问changeDetails方法。不会有任何数据的虚假陈述。