我正在学习如何使用线程,我遇到了这个问题,使用给定的代码我需要说明某个线程是否能够访问某个函数。 这是代码:
public class InsideClass{}
public class SyncClass{
private InsideClass in1;
private InsideClass in2;
public SyncClass(InsideClass i, InsideClass i2){ in1 = i; in2 = i2; }
public synchronized void func1() { System.out.println("in func1"); }
public void func2() { synchronized(in1) { System.out.println("in func2"); }}
public static synchronized void func3() { System.out.println("in func3"); }
public void func4() { synchronized(in2) { System.out.println("in func4"); }}
public synchronized void func5() {
synchronized(in1) {
synchronized(in2){ System.out.println("in func5"); }}
}}
public class MyThread extends Thread{
private SyncClass sc;
public MyThread(SyncClass s) {
sc = s;
}
public void run(){
sc.func1();
sc.func2();
SyncClass.func3();
sc.func4();
sc.func5();
}
}
public class Sys {
public static void main(String[] args) {
InsideClass in1 = new InsideClass();
InsideClass in2= new InsideClass();
SyncClass s1 = new SyncClass(in1,in2);
SyncClass s2 = new SyncClass(in2,in1);
MyThread t1 = new MyThread(s1);
MyThread t2 = new MyThread(s2);
t1.start();
t2.start();
}
}
问题是这样的,假设t1正在执行任务(i)(i = 1,2,3,4),t2能够预先形成func(i + 1)还是会被阻塞?说明。 我写了完整的问题,以防它不清楚。
1)假设t1正在执行func1
a)t2能否预先形成func1?
b)t2能否预先形成func2?
c)t2能否预先形成func3?
d)t2能否预先形成func4?
2)假设t1正在执行func2。
a)t2能否预先形成func2?
b)t2能否预先形成func3?
c)t2能否预先形成func4?
3)假设t1正在执行func3
a)t2能否预先形成func3?
b)t2能否预先形成func4?
4)假设t1正在执行func4
5)func5有一个独特的实现。
a)这种方法有多少种不同的锁?指定他们是谁。
b)func5出现的问题是什么?你会如何解决这个问题?
我不是在寻找所有这些问题的答案(尽管以防万一会很好),但我想得到一个对象含义的解释(在这个例子中为in1 / in2)在同步块内部,当使用这些对象(s1,s2)初始化另外两个对象时。如果t1正在执行同步的func1,那么这对func2进行预处理的效果如何? (如何用相同的对象初始化s1和s2的事实会影响这个问题。)
我希望我的问题很清楚。谢谢!
答案 0 :(得分:1)
synchronized
语句获取给定对象的内在锁,然后执行其正文,然后发布锁
Object lock = new Object();
synchronized(lock) {
...body...
}
Java Runtime Environment(JRE)永远不会允许两个线程同时获取同一对象的内部锁。如果一个线程获得了锁,那么第二个尝试它的线程将被阻塞,直到第一个线程释放锁。
重要的是要知道无论线程如何退出...body...
,锁都会被释放。它return
是否为break
,是否只是结束运行,还是抛出异常都无关紧要。无论如何都会释放锁。
这是一种编写整个身体同步的成员函数的快捷方式。
此:
class MyClass {
synchronized void foobar(...args...) { ...body... }
}
与此完全相同:
class MyClass {
void foobar(...args...) {
synchronized(this) { ...body... }
}
}
synchronized static
函数也是如此,除了它在类对象上同步。
此:
class MyClass {
synchronized static void foobar(...args...) { ...body... }
}
与此完全相同:
class MyClass {
static void foobar(...args...) {
synchronized(MyClass.class) { ...body... }
}
}
记住变量和对象之间的区别非常重要。如果变量synchronized(foo){...}
引用两个不同上下文中的两个不同对象,则两个线程可以同时输入foo
块。 (仔细考虑您的in1
和in2
成员变量!)同样,如果两个线程在不同的对象上运行,则两个不同的线程可以同时调用相同的synchronized
成员函数。 (您的示例有两个不同的SyncClass
实例!)
答案 1 :(得分:0)
代码不能编译。
func5后面有三个左括号和三个近括号
没有紧密的括号可以关闭课程。
如果您有编译器,请编译代码并重新发布。