No Deadlock - but why? Four conditions












-1















I have a Producer Consumer problem and solved it by using semaphores but cannot formally explain which of the four conditions necessary for deadlock I have prevented. It can't be mutual exclusive access or non preemption which leaves either circular-wait or hold and wait. I clearly try to acquire two resources in both the insert and take methods, which hints to hold and wait being existing. Now there's only circular-wait left which I should have prevented but how? Or is my reasoning wrong and it's not circular-wait?



Edit: As people have repeatedly asked me what the problem is with my code because deadlock cannot happen, I want to say there's nothing wrong with it, I just want to know WHY it cannot happen. There are four conditions which need to be met for deadlock to occur which can be found here https://en.wikipedia.org/wiki/Deadlock#Necessary_conditions . I obviously prevented at least one condition or otherwise my code could result in a deadlock. Now I just want to know WHICH of the conditions I prevented.



My Buffers code looks like this:



private String store;
private int capacity;

private int nextIn;
private int nextOut;

private Semaphore mutex = new Semaphore(1);
private Semaphore numAvail = new Semaphore(0); //available items to consume
private Semaphore numFree; //free slots in buffer

public Buffer(int capacity) {
this.capacity = capacity;
this.store = new String[capacity];
numFree = new Semaphore(capacity);
}

public void insert(String item) {

try {
//acquire a free slot in the array
numFree.acquire();

//get permit to insert
mutex.acquire();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}

//critical region - insert to body
store[nextIn] = item;

nextIn++;

//when at end of array begin at index 0 again
if (nextIn == capacity) {
nextIn = 0;
}

//signal that there is an item available
numAvail.release();

//signal that another thread can consume or produce now
mutex.release();
}

public String take() {
String item;

try {
//check if item exists to consume
numAvail.acquire();

//get permit to take
mutex.acquire();

} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
ex.printStackTrace();
}

//critical region
item = store[nextOut];

nextOut++;

if (nextOut == capacity) {
nextOut = 0;
}


//signal other threads that they can consume or produce
mutex.release();

//signal that there is a free slot to insert now
numFree.release();

return item;
}









share|improve this question

























  • but, .. you do not have any possibility of deadlock in this code. what are you trying to prevent?

    – Serge
    Nov 21 '18 at 0:39











  • I solved it but wanted to understand the reason how, that's what my question is about

    – Alex Gogl
    Nov 21 '18 at 0:40













  • the question is, what did you have before, which created the dead lock. If you called insert from take after locking a semaphore (btw, why do you need 2 of them?), then you prevented "hold and wait" by just removing the call. Do not pay much attention to names. Just think what you did and for what reason.

    – Serge
    Nov 21 '18 at 1:10











  • No I have never had a deadlock, I'm just not sure which of the four conditions necessary for it I have prevented

    – Alex Gogl
    Nov 21 '18 at 1:12
















-1















I have a Producer Consumer problem and solved it by using semaphores but cannot formally explain which of the four conditions necessary for deadlock I have prevented. It can't be mutual exclusive access or non preemption which leaves either circular-wait or hold and wait. I clearly try to acquire two resources in both the insert and take methods, which hints to hold and wait being existing. Now there's only circular-wait left which I should have prevented but how? Or is my reasoning wrong and it's not circular-wait?



Edit: As people have repeatedly asked me what the problem is with my code because deadlock cannot happen, I want to say there's nothing wrong with it, I just want to know WHY it cannot happen. There are four conditions which need to be met for deadlock to occur which can be found here https://en.wikipedia.org/wiki/Deadlock#Necessary_conditions . I obviously prevented at least one condition or otherwise my code could result in a deadlock. Now I just want to know WHICH of the conditions I prevented.



My Buffers code looks like this:



private String store;
private int capacity;

private int nextIn;
private int nextOut;

private Semaphore mutex = new Semaphore(1);
private Semaphore numAvail = new Semaphore(0); //available items to consume
private Semaphore numFree; //free slots in buffer

public Buffer(int capacity) {
this.capacity = capacity;
this.store = new String[capacity];
numFree = new Semaphore(capacity);
}

public void insert(String item) {

try {
//acquire a free slot in the array
numFree.acquire();

//get permit to insert
mutex.acquire();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}

//critical region - insert to body
store[nextIn] = item;

nextIn++;

//when at end of array begin at index 0 again
if (nextIn == capacity) {
nextIn = 0;
}

//signal that there is an item available
numAvail.release();

//signal that another thread can consume or produce now
mutex.release();
}

public String take() {
String item;

try {
//check if item exists to consume
numAvail.acquire();

//get permit to take
mutex.acquire();

} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
ex.printStackTrace();
}

//critical region
item = store[nextOut];

nextOut++;

if (nextOut == capacity) {
nextOut = 0;
}


//signal other threads that they can consume or produce
mutex.release();

//signal that there is a free slot to insert now
numFree.release();

return item;
}









share|improve this question

























  • but, .. you do not have any possibility of deadlock in this code. what are you trying to prevent?

    – Serge
    Nov 21 '18 at 0:39











  • I solved it but wanted to understand the reason how, that's what my question is about

    – Alex Gogl
    Nov 21 '18 at 0:40













  • the question is, what did you have before, which created the dead lock. If you called insert from take after locking a semaphore (btw, why do you need 2 of them?), then you prevented "hold and wait" by just removing the call. Do not pay much attention to names. Just think what you did and for what reason.

    – Serge
    Nov 21 '18 at 1:10











  • No I have never had a deadlock, I'm just not sure which of the four conditions necessary for it I have prevented

    – Alex Gogl
    Nov 21 '18 at 1:12














-1












-1








-1








I have a Producer Consumer problem and solved it by using semaphores but cannot formally explain which of the four conditions necessary for deadlock I have prevented. It can't be mutual exclusive access or non preemption which leaves either circular-wait or hold and wait. I clearly try to acquire two resources in both the insert and take methods, which hints to hold and wait being existing. Now there's only circular-wait left which I should have prevented but how? Or is my reasoning wrong and it's not circular-wait?



Edit: As people have repeatedly asked me what the problem is with my code because deadlock cannot happen, I want to say there's nothing wrong with it, I just want to know WHY it cannot happen. There are four conditions which need to be met for deadlock to occur which can be found here https://en.wikipedia.org/wiki/Deadlock#Necessary_conditions . I obviously prevented at least one condition or otherwise my code could result in a deadlock. Now I just want to know WHICH of the conditions I prevented.



My Buffers code looks like this:



private String store;
private int capacity;

private int nextIn;
private int nextOut;

private Semaphore mutex = new Semaphore(1);
private Semaphore numAvail = new Semaphore(0); //available items to consume
private Semaphore numFree; //free slots in buffer

public Buffer(int capacity) {
this.capacity = capacity;
this.store = new String[capacity];
numFree = new Semaphore(capacity);
}

public void insert(String item) {

try {
//acquire a free slot in the array
numFree.acquire();

//get permit to insert
mutex.acquire();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}

//critical region - insert to body
store[nextIn] = item;

nextIn++;

//when at end of array begin at index 0 again
if (nextIn == capacity) {
nextIn = 0;
}

//signal that there is an item available
numAvail.release();

//signal that another thread can consume or produce now
mutex.release();
}

public String take() {
String item;

try {
//check if item exists to consume
numAvail.acquire();

//get permit to take
mutex.acquire();

} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
ex.printStackTrace();
}

//critical region
item = store[nextOut];

nextOut++;

if (nextOut == capacity) {
nextOut = 0;
}


//signal other threads that they can consume or produce
mutex.release();

//signal that there is a free slot to insert now
numFree.release();

return item;
}









share|improve this question
















I have a Producer Consumer problem and solved it by using semaphores but cannot formally explain which of the four conditions necessary for deadlock I have prevented. It can't be mutual exclusive access or non preemption which leaves either circular-wait or hold and wait. I clearly try to acquire two resources in both the insert and take methods, which hints to hold and wait being existing. Now there's only circular-wait left which I should have prevented but how? Or is my reasoning wrong and it's not circular-wait?



Edit: As people have repeatedly asked me what the problem is with my code because deadlock cannot happen, I want to say there's nothing wrong with it, I just want to know WHY it cannot happen. There are four conditions which need to be met for deadlock to occur which can be found here https://en.wikipedia.org/wiki/Deadlock#Necessary_conditions . I obviously prevented at least one condition or otherwise my code could result in a deadlock. Now I just want to know WHICH of the conditions I prevented.



My Buffers code looks like this:



private String store;
private int capacity;

private int nextIn;
private int nextOut;

private Semaphore mutex = new Semaphore(1);
private Semaphore numAvail = new Semaphore(0); //available items to consume
private Semaphore numFree; //free slots in buffer

public Buffer(int capacity) {
this.capacity = capacity;
this.store = new String[capacity];
numFree = new Semaphore(capacity);
}

public void insert(String item) {

try {
//acquire a free slot in the array
numFree.acquire();

//get permit to insert
mutex.acquire();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}

//critical region - insert to body
store[nextIn] = item;

nextIn++;

//when at end of array begin at index 0 again
if (nextIn == capacity) {
nextIn = 0;
}

//signal that there is an item available
numAvail.release();

//signal that another thread can consume or produce now
mutex.release();
}

public String take() {
String item;

try {
//check if item exists to consume
numAvail.acquire();

//get permit to take
mutex.acquire();

} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
ex.printStackTrace();
}

//critical region
item = store[nextOut];

nextOut++;

if (nextOut == capacity) {
nextOut = 0;
}


//signal other threads that they can consume or produce
mutex.release();

//signal that there is a free slot to insert now
numFree.release();

return item;
}






java multithreading deadlock






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 21 '18 at 1:23







Alex Gogl

















asked Nov 21 '18 at 0:25









Alex GoglAlex Gogl

82211




82211













  • but, .. you do not have any possibility of deadlock in this code. what are you trying to prevent?

    – Serge
    Nov 21 '18 at 0:39











  • I solved it but wanted to understand the reason how, that's what my question is about

    – Alex Gogl
    Nov 21 '18 at 0:40













  • the question is, what did you have before, which created the dead lock. If you called insert from take after locking a semaphore (btw, why do you need 2 of them?), then you prevented "hold and wait" by just removing the call. Do not pay much attention to names. Just think what you did and for what reason.

    – Serge
    Nov 21 '18 at 1:10











  • No I have never had a deadlock, I'm just not sure which of the four conditions necessary for it I have prevented

    – Alex Gogl
    Nov 21 '18 at 1:12



















  • but, .. you do not have any possibility of deadlock in this code. what are you trying to prevent?

    – Serge
    Nov 21 '18 at 0:39











  • I solved it but wanted to understand the reason how, that's what my question is about

    – Alex Gogl
    Nov 21 '18 at 0:40













  • the question is, what did you have before, which created the dead lock. If you called insert from take after locking a semaphore (btw, why do you need 2 of them?), then you prevented "hold and wait" by just removing the call. Do not pay much attention to names. Just think what you did and for what reason.

    – Serge
    Nov 21 '18 at 1:10











  • No I have never had a deadlock, I'm just not sure which of the four conditions necessary for it I have prevented

    – Alex Gogl
    Nov 21 '18 at 1:12

















but, .. you do not have any possibility of deadlock in this code. what are you trying to prevent?

– Serge
Nov 21 '18 at 0:39





but, .. you do not have any possibility of deadlock in this code. what are you trying to prevent?

– Serge
Nov 21 '18 at 0:39













I solved it but wanted to understand the reason how, that's what my question is about

– Alex Gogl
Nov 21 '18 at 0:40







I solved it but wanted to understand the reason how, that's what my question is about

– Alex Gogl
Nov 21 '18 at 0:40















the question is, what did you have before, which created the dead lock. If you called insert from take after locking a semaphore (btw, why do you need 2 of them?), then you prevented "hold and wait" by just removing the call. Do not pay much attention to names. Just think what you did and for what reason.

– Serge
Nov 21 '18 at 1:10





the question is, what did you have before, which created the dead lock. If you called insert from take after locking a semaphore (btw, why do you need 2 of them?), then you prevented "hold and wait" by just removing the call. Do not pay much attention to names. Just think what you did and for what reason.

– Serge
Nov 21 '18 at 1:10













No I have never had a deadlock, I'm just not sure which of the four conditions necessary for it I have prevented

– Alex Gogl
Nov 21 '18 at 1:12





No I have never had a deadlock, I'm just not sure which of the four conditions necessary for it I have prevented

– Alex Gogl
Nov 21 '18 at 1:12












1 Answer
1






active

oldest

votes


















1














I believe that you prevented circular wait.



Circular wait occurs when each process waits for a resource which is being held by another process.



In your example, the only resource that is being waited for while holding another resource is the mutex. However, a thread that holds the mutex does never wait for anything.



For circular wait to occur, the mutex-holding thread would need to wait for something while having the mutex.






share|improve this answer

























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53403614%2fno-deadlock-but-why-four-conditions%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1














    I believe that you prevented circular wait.



    Circular wait occurs when each process waits for a resource which is being held by another process.



    In your example, the only resource that is being waited for while holding another resource is the mutex. However, a thread that holds the mutex does never wait for anything.



    For circular wait to occur, the mutex-holding thread would need to wait for something while having the mutex.






    share|improve this answer






























      1














      I believe that you prevented circular wait.



      Circular wait occurs when each process waits for a resource which is being held by another process.



      In your example, the only resource that is being waited for while holding another resource is the mutex. However, a thread that holds the mutex does never wait for anything.



      For circular wait to occur, the mutex-holding thread would need to wait for something while having the mutex.






      share|improve this answer




























        1












        1








        1







        I believe that you prevented circular wait.



        Circular wait occurs when each process waits for a resource which is being held by another process.



        In your example, the only resource that is being waited for while holding another resource is the mutex. However, a thread that holds the mutex does never wait for anything.



        For circular wait to occur, the mutex-holding thread would need to wait for something while having the mutex.






        share|improve this answer















        I believe that you prevented circular wait.



        Circular wait occurs when each process waits for a resource which is being held by another process.



        In your example, the only resource that is being waited for while holding another resource is the mutex. However, a thread that holds the mutex does never wait for anything.



        For circular wait to occur, the mutex-holding thread would need to wait for something while having the mutex.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 21 '18 at 1:32

























        answered Nov 21 '18 at 1:08









        mmarkusmmarkus

        336




        336






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53403614%2fno-deadlock-but-why-four-conditions%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            "Incorrect syntax near the keyword 'ON'. (on update cascade, on delete cascade,)

            Alcedinidae

            Origin of the phrase “under your belt”?