Java: 为什么我的同步输出还是那么随机
Java: Why is my synchronized output still so random
所以我第一次练习同步。我正在尝试实施 Oracle Java 并发教程中大体描述的实践概念。
想法是有一个特殊的 Counter 对象,具有递增、递减和显示值的方法。我的目标是通过两个不同的线程获取它 运行 以产生 运行dom 冲突,然后通过同步来解决这些冲突。到目前为止,我觉得第二部分不起作用,我无法弄清楚我做错了什么。
我在下面粘贴的代码很简单。有两个线程,有两个 运行nables。每个 运行 启用:
1) 包含对同一个 Counter 对象的引用
2) 运行s 循环五次
3)每次循环休眠1秒运行s
4) 打印计数器的当前值。
MyRunnable1 和 MyRunnable2 之间的唯一区别是第一个增加计数器,第二个减少计数器。
显然,当我 运行 它没有同步方法时,它产生了 运行dom 结果。但即使在我同步方法之后,结果显然仍然是 运行dom.
样本结果 1:
1个
0
1个
0
1个
0
-1
0
1个
0
样本结果 2:
-1
0
1个
0
1个
0
1个
0
-1
0
我认为它应该是什么:它应该始终如一地运行 1 0 1 0 1 0 等等,直到所有循环都完成。如果我在那里错了,如果这是我对线程行为的思考方式,请指出。
下面是我的代码。所有 thoughts/advice 表示赞赏。这是我第一次尝试以任何方式使用同步,我想记下它,因为它是一个非常重要的概念。
public class CounterSync {
public static void main(String[] args){
Counter c = new Counter();
Thread t1 = new Thread(new MyRunnable1(c));
Thread t2 = new Thread(new MyRunnable2(c));
t1.start();
t2.start();
System.out.println("Done");
}
public static class Counter{
private int c = 0;
public synchronized void increment(){
c++;
}
public synchronized void decrement(){
c--;
}
public synchronized int value(){
return c;
}
}
public static class MyRunnable1 implements Runnable{
private Counter c;
public MyRunnable1(Counter c){
this.c = c;
}
@Override
public void run(){
try{
for(int i = 0; i < 5; i++){
Thread.sleep(1000);
c.increment();
System.out.println(c.value());
}
}catch(InterruptedException ex){
ex.printStackTrace();
}
}
}
public static class MyRunnable2 implements Runnable{
private Counter c;
public MyRunnable2(Counter c){
this.c = c;
}
@Override
public void run(){
try{
for(int i = 0; i < 5; i++){
Thread.sleep(1000);
c.decrement();
System.out.println(c.value());
}
}catch(InterruptedException ex){
ex.printStackTrace();
}
}
}
}
同步不代表有序。也许 'synchronization' 这个词具有误导性。在您的情况下,当一个人具有同步方法时,这意味着在给定的瞬间,最多一个线程可以 运行 一个 同步 方法在相关对象上。
您可以将 'synchronized' 读为 'one at a time'。
当您有多个线程时运行,每个线程的进度由系统决定。此外,Thread.sleep
保证在给定的时间间隔内至少 睡眠,但 不 是准确的。这两个事实结合起来会给你随机排序。
所以我第一次练习同步。我正在尝试实施 Oracle Java 并发教程中大体描述的实践概念。
想法是有一个特殊的 Counter 对象,具有递增、递减和显示值的方法。我的目标是通过两个不同的线程获取它 运行 以产生 运行dom 冲突,然后通过同步来解决这些冲突。到目前为止,我觉得第二部分不起作用,我无法弄清楚我做错了什么。
我在下面粘贴的代码很简单。有两个线程,有两个 运行nables。每个 运行 启用:
1) 包含对同一个 Counter 对象的引用 2) 运行s 循环五次 3)每次循环休眠1秒运行s 4) 打印计数器的当前值。
MyRunnable1 和 MyRunnable2 之间的唯一区别是第一个增加计数器,第二个减少计数器。
显然,当我 运行 它没有同步方法时,它产生了 运行dom 结果。但即使在我同步方法之后,结果显然仍然是 运行dom.
样本结果 1: 1个 0 1个 0 1个 0 -1 0 1个 0
样本结果 2: -1 0 1个 0 1个 0 1个 0 -1 0
我认为它应该是什么:它应该始终如一地运行 1 0 1 0 1 0 等等,直到所有循环都完成。如果我在那里错了,如果这是我对线程行为的思考方式,请指出。
下面是我的代码。所有 thoughts/advice 表示赞赏。这是我第一次尝试以任何方式使用同步,我想记下它,因为它是一个非常重要的概念。
public class CounterSync {
public static void main(String[] args){
Counter c = new Counter();
Thread t1 = new Thread(new MyRunnable1(c));
Thread t2 = new Thread(new MyRunnable2(c));
t1.start();
t2.start();
System.out.println("Done");
}
public static class Counter{
private int c = 0;
public synchronized void increment(){
c++;
}
public synchronized void decrement(){
c--;
}
public synchronized int value(){
return c;
}
}
public static class MyRunnable1 implements Runnable{
private Counter c;
public MyRunnable1(Counter c){
this.c = c;
}
@Override
public void run(){
try{
for(int i = 0; i < 5; i++){
Thread.sleep(1000);
c.increment();
System.out.println(c.value());
}
}catch(InterruptedException ex){
ex.printStackTrace();
}
}
}
public static class MyRunnable2 implements Runnable{
private Counter c;
public MyRunnable2(Counter c){
this.c = c;
}
@Override
public void run(){
try{
for(int i = 0; i < 5; i++){
Thread.sleep(1000);
c.decrement();
System.out.println(c.value());
}
}catch(InterruptedException ex){
ex.printStackTrace();
}
}
}
}
同步不代表有序。也许 'synchronization' 这个词具有误导性。在您的情况下,当一个人具有同步方法时,这意味着在给定的瞬间,最多一个线程可以 运行 一个 同步 方法在相关对象上。
您可以将 'synchronized' 读为 'one at a time'。
当您有多个线程时运行,每个线程的进度由系统决定。此外,Thread.sleep
保证在给定的时间间隔内至少 睡眠,但 不 是准确的。这两个事实结合起来会给你随机排序。