Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/347.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java-多线程练习_Java_Multithreading - Fatal编程技术网

Java-多线程练习

Java-多线程练习,java,multithreading,Java,Multithreading,我要做作业,问题是: 查看此程序,运行它并找到问题,然后修复它 以下是节目: package serie02; import java.util.ArrayList; class S2Es1Timer { private long startTime = -1; private long stopTime = -1; final protected void start() { startTime = System.currentTimeMillis

我要做作业,问题是: 查看此程序,运行它并找到问题,然后修复它

以下是节目:

package serie02;

import java.util.ArrayList;

class S2Es1Timer {
    private long startTime = -1;
    private long stopTime = -1;

    final protected void start() {
        startTime = System.currentTimeMillis();
    }

    final protected void stop() {
        stopTime = System.currentTimeMillis();
    }

    final public long getElapsedTime() {
        if (startTime < 0 || stopTime < 0)
            return 0;
        return stopTime - startTime;
    }
}

class S2Es1SharedState {
    boolean sharedState = false;
}

class S2Es1Worker implements Runnable {
    private static final long START_VALUE = 1000000000;
    private final int id;
    private final S2Es1Timer timer;
    private final S2Es1SharedState state;
    private long localCounter = START_VALUE;

    public S2Es1Worker(final int id, final S2Es1SharedState state) {
        this.id = id;
        timer = new S2Es1Timer();
        this.state = state;
        log("created");
    }

    @Override
    public void run() {
        timer.start();

        while (--localCounter > 0) {
            if (state.sharedState) {
                timer.stop();
                log("sharedState has already been set by another worker. localCounter: "
                        + ((100.0 * localCounter) / START_VALUE)
                        + " % from goal");
                return;
            }
        }
        // richiedi accesso esclusivo per scrittura
        state.sharedState = true;

        timer.stop();
        log("sharedState has been set");
    }

    final protected void log(final String s) {
        System.out.println(this.getClass().getSimpleName() + id + ": " + s);
    }

    final protected void logElapseTime() {
        log("time: " + timer.getElapsedTime() + " ms");
    }
}

public class S2Esercizio1 {
    private final static int NUM_WORKERS = 10;

    public static void main(final String[] args) {
        final S2Es1Timer mainTimer = new S2Es1Timer();
        final ArrayList<Thread> threads = new ArrayList<Thread>();
        final ArrayList<S2Es1Worker> workers = new ArrayList<S2Es1Worker>();
        final S2Es1SharedState myShare = new S2Es1SharedState();

        // Crea 10 Workers
        for (int i = 0; i < NUM_WORKERS; i++) {
            final S2Es1Worker worker = new S2Es1Worker(i, myShare);
            workers.add(worker);
            threads.add(new Thread(worker));
        }

        System.out.println("Simulation started");
        System.out.println("------------------------------------");
        mainTimer.start();

        // Fa partire tutte le threads
        for (final Thread t : threads)
            t.start();

        try {
            // Attende che tutte le threads terminano
            for (final Thread t : threads)
                t.join();
        } catch (final InterruptedException e) {
            /* Unhandled exception */
        }
        mainTimer.stop();

        System.out.println("------------------------------------");
        for (final S2Es1Worker worker : workers)
            worker.logElapseTime();
        System.out.println("Simulation time: " + mainTimer.getElapsedTime()
                + " ms");
        System.out.println("Simulation finished");
    }
}
我认为这是一个可见性问题,我的意思是当第一个线程完成循环并将共享可变变量sharedState设置为true时,其他线程继续循环,因为它们在缓存cpu中有脏读,我有4个cpu。 所以我能做的唯一一件好事就是用键volatile设置sharedState变量。通过这种方式,每个线程都读取正确的值。我浪费了时间,因为这个值现在由主内存而不是cpu缓存捕获。 另一个解决方案是:使用ReentrantReadWriteLock。 因此,可以通过以下方式写入S2Es1SharedState类:

class S2Es1SharedState {
    private final ReadWriteLock lock = new ReentrantReadWriteLock();
    private final Lock readLock = lock.readLock(); 
    private final Lock writeLock = lock.writeLock(); 
    boolean sharedState = false;

    public boolean getSharedState() {
        readLock.lock();
        try {
            return sharedState;
        } finally {
            readLock.unlock();
        }
    }
    public void setSharedState() {
        writeLock.lock();
        try {
            this.sharedState = true;
        }
        finally {
            writeLock.unlock(); 
        }       
    }
}
我认为这个解决方案是可行的,因为锁也提供了一个正确的可见性,但我认为需要花费很多时间,因为这样在循环内部我不使用缓存cpu,而只使用主内存。这次手术需要时间。
我不确定我的分析,出于这个原因,我更愿意问你

一般来说,你的教授需要更新;现在没有人以这种方式使用线程——事实上,自从执行器出现以来,再也没有人使用线程了framework@fge翻译是:请求对writingOK的独占访问权,脱离主题,但你怎么说再次询问?我以为chiedere是想问的?@fge executor下学期,他希望我以这种方式开始,不要问我为什么
class S2Es1SharedState {
    private final ReadWriteLock lock = new ReentrantReadWriteLock();
    private final Lock readLock = lock.readLock(); 
    private final Lock writeLock = lock.writeLock(); 
    boolean sharedState = false;

    public boolean getSharedState() {
        readLock.lock();
        try {
            return sharedState;
        } finally {
            readLock.unlock();
        }
    }
    public void setSharedState() {
        writeLock.lock();
        try {
            this.sharedState = true;
        }
        finally {
            writeLock.unlock(); 
        }       
    }
}