加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 为什么这些代码块没有给出相同的结果?

发布时间:2020-12-15 02:15:28 所属栏目:Java 来源:网络整理
导读:所以我是这个Thread的新手,我写了一个简单的程序来测试避免竞争条件.我的第一次尝试是使用Named Inner类: /* App1.java */package ehsan;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class App1{ private f
所以我是这个Thread的新手,我写了一个简单的程序来测试避免竞争条件.我的第一次尝试是使用Named Inner类:

/* App1.java */

package ehsan;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class App1{
    private final int poolSize = 10;
    private final int numLoop = 5;
    private int lastThread = 0;

    public App1() {
        ExecutorService taskList = Executors.newFixedThreadPool(poolSize);
        for (int i = 0;i < poolSize;i++) {
            taskList.execute(new Counter());
        }
        taskList.shutdown();
    }

    private class Counter implements Runnable{

        @Override
        public void run() {
            synchronized (this) {
                int currentThread = lastThread;
                System.out.println("Current thread : "+currentThread);
                lastThread = lastThread + 1;
            }
            System.out.println("Thread was executed");
        }
    }

}

和App1Test.java:

package ehsan;

import java.io.IOException;

public class Test {
    public static void main(String[] args) throws IOException {
        new App1();
    }
}

结果它显示:

Current thread : 0
Thread was executed
Current thread : 1
Thread was executed
Current thread : 1
Thread was executed
Current thread : 3
Thread was executed
Current thread : 4
Thread was executed
Current thread : 5
Thread was executed
Current thread : 6
Thread was executed
Current thread : 7
Thread was executed
Current thread : 6
Current thread : 8
Thread was executed
Thread was executed

整个事情变得混乱,即使我在那里使用同步,我也面临着竞争条件.

但我的第二次尝试有效! :

package ehsan;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class App1 implements Runnable{
    private final int poolSize = 10;
    private final int numLoop = 5;
    private int lastThread = 0;

    public App1() {
        ExecutorService taskList = Executors.newFixedThreadPool(poolSize);
        for (int i = 0;i < poolSize;i++) {
            taskList.execute(this);
        }
        taskList.shutdown();
    }

    @Override
    public void run() {
        synchronized (this) {
            int currentThread = lastThread;
            System.out.println("Current thread : "+currentThread);
            lastThread = lastThread + 1;
            System.out.println("Thread was executed");
        }
    }
}

结果如我所料:

Current thread : 0
Thread was executed
Current thread : 1
Thread was executed
Current thread : 2
Thread was executed
Current thread : 3
Thread was executed
Current thread : 4
Thread was executed
Current thread : 5
Thread was executed
Current thread : 6
Thread was executed
Current thread : 7
Thread was executed
Current thread : 8
Thread was executed
Current thread : 9
Thread was executed

所以我的问题是为什么我的第一次尝试不起作用而第二次尝试起了很大作用?感谢您的帮助,我是多线程编程的初学者!

解决方法

在第一个程序中,您创建一个不同的Counter实例作为Runnable,其run()方法由每个线程执行,因此synchronized(this)对每个线程使用不同的锁,因此代码不是线程安全的.如果您使用相同的Counter实例而不是为每个线程创建一个新实例,则此程序也将按预期运行.

Counter counter = new Counter();
    for (int i = 0;i < poolSize;i++) {
        taskList.execute(counter);
    }

在第二个程序中,您使用与Runnable相同的App1实例,其run()方法由所有线程执行,因此synchronized(this)对所有线程使用相同的锁.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读