同时执行的同步方法
synchronized methods executing simulaneously
根据 synchronized 关键字,如果应用于方法,则它会获取对象锁,并且具有相同实例的多个方法将无法并发执行这些方法。
但在下面的示例中,执行是同时发生的。
请看一看:-
public class ncuie extends Thread{
int b;
ncuie(int a){
b=a;
}
public synchronized void abc() throws InterruptedException {
for (int i = 0; i < 10; i++) {
System.out.println("thread 1 "+i);
}
}
public synchronized void pqr() throws InterruptedException {
for (int i = 0; i < 10; i++) {
System.out.println("thread 2 "+i);
}
}
public void run() {
try {
if(b==5) {
abc();
}
if(b==10) {
pqr();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
Thread t=new ncuie(5);
Thread t1=new ncuie(10);
t.start();
t1.start();
}
}
根据输出,有时执行线程 1,有时执行线程 2。
理想情况下,一个线程应该获得锁并完成执行,然后只有第二个线程应该启动。
输出:-
thread 1 0
thread 1 1
thread 2 0
thread 2 1
thread 2 2
thread 1 2
thread 1 3
thread 1 4
thread 1 5
thread 1 6
thread 1 7
thread 1 8
thread 2 3
thread 2 4
thread 2 5
thread 2 6
thread 1 9
thread 2 7
thread 2 8
thread 2 9
synchronized
获取 this
上的锁。您有两个 ncuie
class 实例,因此将它们同时锁定是完全没问题的。
要解决它,您需要在线程之间共享一些实例。我建议创建新的 Object
并将其传递给 constrictor。
如果某些方法以某种方式更改内部状态,而其他方法在同一实例上运行,则您通常会在您的实例上同步惹上麻烦。通过在非静态方法上使用 synchronized
关键字,或者通过编写 synchronized(this) {...}
.
,可以在当前实例 (this
) 上同步
如果您的方法更改状态的方式甚至在 class 的不同实例 上操作 的方法也会受到影响,您可以在 [=31] 上同步=] 对象。你通过写 synchronized(MyClass.class) {...}
.
来做到这一点
如果您的静态方法需要与同一 class 的其他静态方法同步,您可以使用 synchronized
关键字在 class 对象上同步静态方法。
请注意,实例级同步和 class 级同步是完全独立的,这意味着,当 class 同步方法运行时,实例同步方法不会被阻塞。
在您的情况下,您在实例上进行了同步,并且您有两个不同的实例,因此它们不会相互阻塞。
根据 synchronized 关键字,如果应用于方法,则它会获取对象锁,并且具有相同实例的多个方法将无法并发执行这些方法。
但在下面的示例中,执行是同时发生的。 请看一看:-
public class ncuie extends Thread{
int b;
ncuie(int a){
b=a;
}
public synchronized void abc() throws InterruptedException {
for (int i = 0; i < 10; i++) {
System.out.println("thread 1 "+i);
}
}
public synchronized void pqr() throws InterruptedException {
for (int i = 0; i < 10; i++) {
System.out.println("thread 2 "+i);
}
}
public void run() {
try {
if(b==5) {
abc();
}
if(b==10) {
pqr();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
Thread t=new ncuie(5);
Thread t1=new ncuie(10);
t.start();
t1.start();
}
}
根据输出,有时执行线程 1,有时执行线程 2。 理想情况下,一个线程应该获得锁并完成执行,然后只有第二个线程应该启动。
输出:-
thread 1 0
thread 1 1
thread 2 0
thread 2 1
thread 2 2
thread 1 2
thread 1 3
thread 1 4
thread 1 5
thread 1 6
thread 1 7
thread 1 8
thread 2 3
thread 2 4
thread 2 5
thread 2 6
thread 1 9
thread 2 7
thread 2 8
thread 2 9
synchronized
获取 this
上的锁。您有两个 ncuie
class 实例,因此将它们同时锁定是完全没问题的。
要解决它,您需要在线程之间共享一些实例。我建议创建新的 Object
并将其传递给 constrictor。
如果某些方法以某种方式更改内部状态,而其他方法在同一实例上运行,则您通常会在您的实例上同步惹上麻烦。通过在非静态方法上使用 synchronized
关键字,或者通过编写 synchronized(this) {...}
.
this
) 上同步
如果您的方法更改状态的方式甚至在 class 的不同实例 上操作 的方法也会受到影响,您可以在 [=31] 上同步=] 对象。你通过写 synchronized(MyClass.class) {...}
.
如果您的静态方法需要与同一 class 的其他静态方法同步,您可以使用 synchronized
关键字在 class 对象上同步静态方法。
请注意,实例级同步和 class 级同步是完全独立的,这意味着,当 class 同步方法运行时,实例同步方法不会被阻塞。
在您的情况下,您在实例上进行了同步,并且您有两个不同的实例,因此它们不会相互阻塞。