If the method behaves synchronously

The following is a snippet outlining the purpose of this unit test. The figure below shows that it createFileperforms only one task, which is already known as a thread-safe operation.

Thus, the idea is more connected with the test than with the real work; to prove beyond the shadow of doubt, the behavior of a thread-protected method is that it behaves as we have already proven historically.

public static final synchronized void createFile(final File file) throws IOException {
    file.createNewFile();
}

@Test
public void testCreateFileThreadSafety() throws Exception {
    for (int i = 1; i < 50; i++) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    createFile(new File(i+".txt"));
                    new File(i+".txt").delete();
                } catch (IOException ex) {
                   System.out.println(ex.getMessage());
                }
            }
        }).start();
        assertTrue(file.getParentFile().listFiles().length == 0);
    }
}

EDIT:

What happens now: a stream is created, a file is created, the file is deleted, the threads die, they say nothing is proved, and they repeat

Expected: threads must begin and be approved to ensure that only one file is created at a time and that other threads are waiting and not executing a method

DOUBLE EDITING:

unit test, , ( )

+4
2

, , . , , , :

static AtomicInteger c = new AtomicInteger();

public void knownNonThreadSafeMethod(final File file) throws IOException {
    int t = c.incrementAndGet();
    doSomething();   
    Thread.yield(); //try to force race conditions, remove in prod
    assert t == c.intValue();
}

int i.s.o. AtomicInteger .

static int c = 0;

public void knownNonThreadSafeMethod(final File file) throws IOException {
    int t = ++c;
    doSomething();   
    assert t == c; //smart-ass compiler will optimize to 'true'
}

AtomicInteger , , .

, JUnit, - . , AspectJ?

+1

File, createNewFile :

class TestFile extends File {

    private final AtomicBoolean isCreated = new AtomicBoolean(false);
    private boolean isSynchronizationFailed = false;

    public boolean createNewFile() throws IOException {
        if (isCreated.compareAndSet(false, true)) {
            // give other threads chance to get here
            try {
                Thread.sleep(1000L);
            } catch (InterruptedException e) {
            }
            // cleanup
            isCreated.set(false);
        } else {
            isSynchronizationFailed = true;
        }
        return super.createNewFile();
    }
}

, isSynchronizationFailed, .

- createNewFile , isSynchronizationFailed, true.

+1

Source: https://habr.com/ru/post/1671156/


All Articles