synchronized 关键字给出了预期的输出,但对不同线程调用该方法的顺序不满意
synchronized keyword is giving the expected output but not satisfied with the order in which the method is called by different threads
下面是我的 3 classes(threads) 实现 Runnable 接口:
public class Thread1 implements Runnable {
Shared s;
public Thread1(Shared s){
this.s = s;
}
@Override
public void run() {
System.out.println("Sum of 10 and 20 by " + Thread.currentThread().getName() + " is "+ s.add(10, 20));
}
}
public class Thread2 implements Runnable {
Shared s;
public Thread2(Shared s){
this.s = s;
}
@Override
public void run() {
System.out.println("Sum of 100 and 200 by " + Thread.currentThread().getName() + " is " + s.add(100, 200));
}
}
public class Thread3 implements Runnable {
Shared s;
public Thread3(Shared s){
this.s = s;
}
@Override
public void run() {
System.out.println("Sum of 1000 and 2000 by " + Thread.currentThread().getName() + " is " + s.add(1000, 2000));
}
}
下面是class,其对象在这些线程之间共享:
public class Shared {
private int x;
private int y;
synchronized public int add(int a, int b) {
x = a;
y = b;
try {
System.out.println(Thread.currentThread().getName() + "is going into sleep state");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return x + y;
}
}
最后,这就是我启动线程和传递共享对象的方式:
public static void main(String[] args) {
Shared s = new Shared();
Thread t1 = new Thread(new Thread1(s), "Thread-1");
Thread t2 = new Thread(new Thread2(s), "Thread-2");
Thread t3 = new Thread(new Thread3(s), "Thread-3");
t1.start();
t2.start();
t3.start();
}
这是我得到的正确输出:
Thread-2is going into sleep state
Thread-1is going into sleep state
Sum of 100 and 200 by Thread-2 is 300
Thread-3is going into sleep state
Sum of 10 and 20 by Thread-1 is 30
Sum of 1000 and 2000 by Thread-3 is 3000
但是如果你看到这里,Thread-1 在 Thread-2 完成它的工作之前开始执行 add 方法(这是同步的)。
由于 Thread-2 进入休眠状态,因此它自己也获得了锁,并且不应允许其他线程进入 add(...) 方法。 Thread-1 或 Thread-3 只能在 Thread-2 完成后才开始执行 add(...) 方法。所以,我期待的输出是:
Thread-2is going into sleep state
Sum of 100 and 200 by Thread-2 is 300
Thread-1is going into sleep state
Sum of 10 and 20 by Thread-1 is 30
Thread-3is going into sleep state
Sum of 1000 and 2000 by Thread-3 is 3000
请告诉我哪里做错了或者输出结果是这样的,如果是,请告诉原因。
原因是System.out.println()
速度很慢。
您可以使用它从 运行() 方法内部和 add()
内部发送消息。无法保证 sysout 中的消息一致。
我重写了Shared
如下:
public class Shared {
private int x;
private int y;
synchronized public int add(int a, int b) {
x = a;
y = b;
try {
long now = System.currentTimeMillis() - start;
Thread.sleep(1000);
// notice FIRST sleep and THEN sysout
System.out.println(Thread.currentThread().getName() + " calculation has taken place at time " + now);
} catch (InterruptedException e) {
e.printStackTrace();
}
return x + y;
}
public static long start;
public static void main(String[] args) {
start = System.currentTimeMillis();
Shared s = new Shared();
Thread t1 = new Thread(new Thread1(s), "Thread-1");
Thread t2 = new Thread(new Thread2(s), "Thread-2");
Thread t3 = new Thread(new Thread3(s), "Thread-3");
t1.start();
t2.start();
t3.start();
}
}
每个线程现在看起来像:
public class Thread1 implements Runnable {
Shared s;
public Thread1(Shared s) {
this.s = s;
}
@Override
public void run() {
int result = s.add(10, 20);
long now= System.currentTimeMillis()-Shared.start;
System.out.println("Sum of 10 and 20 by " + Thread.currentThread().getName() + " is " + result+ " found at "+ now);
}
}
生成以下输出:
Thread-1 calculation has taken place at time 2
Sum of 10 and 20 by Thread-1 is 30 found at 1005
Thread-2 calculation has taken place at time 1005
Sum of 100 and 200 by Thread-2 is 300 found at 2006
Thread-3 calculation has taken place at time 2006
Sum of 1000 and 2000 by Thread-3 is 3000 found at 3007
每个线程都在 add()
中阻塞。
等到后面显示结果的时候,下一个线程已经开始计算了。
注意 add()
现在首先是 sysout(很慢),它发生在睡眠期间,这给了它足够的时间。
您需要同步s
如下图:
@Override
public void run() {
synchronized (s) {
System.out.println("Sum of 10 and 20 by " + Thread.currentThread().getName() + " is " + s.add(10, 20));
}
}
在 类、Thread2
和 Thread3
中也这样做。检查 this 以获得解释。
下面是我的 3 classes(threads) 实现 Runnable 接口:
public class Thread1 implements Runnable {
Shared s;
public Thread1(Shared s){
this.s = s;
}
@Override
public void run() {
System.out.println("Sum of 10 and 20 by " + Thread.currentThread().getName() + " is "+ s.add(10, 20));
}
}
public class Thread2 implements Runnable {
Shared s;
public Thread2(Shared s){
this.s = s;
}
@Override
public void run() {
System.out.println("Sum of 100 and 200 by " + Thread.currentThread().getName() + " is " + s.add(100, 200));
}
}
public class Thread3 implements Runnable {
Shared s;
public Thread3(Shared s){
this.s = s;
}
@Override
public void run() {
System.out.println("Sum of 1000 and 2000 by " + Thread.currentThread().getName() + " is " + s.add(1000, 2000));
}
}
下面是class,其对象在这些线程之间共享:
public class Shared {
private int x;
private int y;
synchronized public int add(int a, int b) {
x = a;
y = b;
try {
System.out.println(Thread.currentThread().getName() + "is going into sleep state");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return x + y;
}
}
最后,这就是我启动线程和传递共享对象的方式:
public static void main(String[] args) {
Shared s = new Shared();
Thread t1 = new Thread(new Thread1(s), "Thread-1");
Thread t2 = new Thread(new Thread2(s), "Thread-2");
Thread t3 = new Thread(new Thread3(s), "Thread-3");
t1.start();
t2.start();
t3.start();
}
这是我得到的正确输出:
Thread-2is going into sleep state
Thread-1is going into sleep state
Sum of 100 and 200 by Thread-2 is 300
Thread-3is going into sleep state
Sum of 10 and 20 by Thread-1 is 30
Sum of 1000 and 2000 by Thread-3 is 3000
但是如果你看到这里,Thread-1 在 Thread-2 完成它的工作之前开始执行 add 方法(这是同步的)。 由于 Thread-2 进入休眠状态,因此它自己也获得了锁,并且不应允许其他线程进入 add(...) 方法。 Thread-1 或 Thread-3 只能在 Thread-2 完成后才开始执行 add(...) 方法。所以,我期待的输出是:
Thread-2is going into sleep state
Sum of 100 and 200 by Thread-2 is 300
Thread-1is going into sleep state
Sum of 10 and 20 by Thread-1 is 30
Thread-3is going into sleep state
Sum of 1000 and 2000 by Thread-3 is 3000
请告诉我哪里做错了或者输出结果是这样的,如果是,请告诉原因。
原因是System.out.println()
速度很慢。
您可以使用它从 运行() 方法内部和 add()
内部发送消息。无法保证 sysout 中的消息一致。
我重写了Shared
如下:
public class Shared {
private int x;
private int y;
synchronized public int add(int a, int b) {
x = a;
y = b;
try {
long now = System.currentTimeMillis() - start;
Thread.sleep(1000);
// notice FIRST sleep and THEN sysout
System.out.println(Thread.currentThread().getName() + " calculation has taken place at time " + now);
} catch (InterruptedException e) {
e.printStackTrace();
}
return x + y;
}
public static long start;
public static void main(String[] args) {
start = System.currentTimeMillis();
Shared s = new Shared();
Thread t1 = new Thread(new Thread1(s), "Thread-1");
Thread t2 = new Thread(new Thread2(s), "Thread-2");
Thread t3 = new Thread(new Thread3(s), "Thread-3");
t1.start();
t2.start();
t3.start();
}
}
每个线程现在看起来像:
public class Thread1 implements Runnable {
Shared s;
public Thread1(Shared s) {
this.s = s;
}
@Override
public void run() {
int result = s.add(10, 20);
long now= System.currentTimeMillis()-Shared.start;
System.out.println("Sum of 10 and 20 by " + Thread.currentThread().getName() + " is " + result+ " found at "+ now);
}
}
生成以下输出:
Thread-1 calculation has taken place at time 2
Sum of 10 and 20 by Thread-1 is 30 found at 1005
Thread-2 calculation has taken place at time 1005
Sum of 100 and 200 by Thread-2 is 300 found at 2006
Thread-3 calculation has taken place at time 2006
Sum of 1000 and 2000 by Thread-3 is 3000 found at 3007
每个线程都在 add()
中阻塞。
等到后面显示结果的时候,下一个线程已经开始计算了。
注意 add()
现在首先是 sysout(很慢),它发生在睡眠期间,这给了它足够的时间。
您需要同步s
如下图:
@Override
public void run() {
synchronized (s) {
System.out.println("Sum of 10 and 20 by " + Thread.currentThread().getName() + " is " + s.add(10, 20));
}
}
在 类、Thread2
和 Thread3
中也这样做。检查 this 以获得解释。