{"id":11398,"date":"2022-02-21T06:52:52","date_gmt":"2022-02-21T06:52:52","guid":{"rendered":"https:\/\/www.softwareeverydayblog.com\/?p=11398"},"modified":"2022-02-21T06:54:57","modified_gmt":"2022-02-21T06:54:57","slug":"programming-problem-print-foobar-alternately","status":"publish","type":"post","link":"https:\/\/www.softwareeverydayblog.com\/?p=11398","title":{"rendered":"[Programming Problem] Print FooBar Alternately"},"content":{"rendered":"<p>Suppose you are given the following code:<\/p>\n<pre lang=\"java\">\r\nclass FooBar {\r\n  public void foo() {\r\n    for (int i = 0; i < n; i++) {\r\n      print(\"foo\");\r\n    }\r\n  }\r\n\r\n  public void bar() {\r\n    for (int i = 0; i < n; i++) {\r\n      print(\"bar\");\r\n    }\r\n  }\r\n}\r\n<\/pre>\n<p>The same instance of FooBar will be passed to two different threads:<\/p>\n<ul>\n<li>thread A will call foo(), while<\/li>\n<li>thread B will call bar().<\/li>\n<\/ul>\n<p>Modify the given program to output \"foobar\" n times.<\/p>\n<p><strong>Example 1<\/strong>:<br \/>\nInput: n = 1<br \/>\nOutput: \"foobar\"<br \/>\nExplanation: There are two threads being fired asynchronously. One of them calls foo(), while the other calls bar().<br \/>\n\"foobar\" is being output 1 time.<\/p>\n<p><strong>Example 2<\/strong>:<br \/>\nInput: n = 2<br \/>\nOutput: \"foobarfoobar\"<br \/>\nExplanation: \"foobar\" is being output 2 times.<\/p>\n<p>[<a href=\"https:\/\/leetcode.com\/problems\/print-foobar-alternately\/\" rel=\"noopener\" target=\"_blank\">Problem Link<\/a>]<\/p>\n<p>Why use <a href=\"https:\/\/docs.oracle.com\/javase\/7\/docs\/api\/java\/util\/concurrent\/Semaphore.html\" rel=\"noopener\" target=\"_blank\">Semaphore<\/a> and not <a href=\"https:\/\/docs.oracle.com\/javase\/7\/docs\/api\/java\/util\/concurrent\/locks\/ReentrantLock.html\" rel=\"noopener\" target=\"_blank\">ReentrantLock<\/a>?<\/p>\n<p>A semaphore initialized to one, and which is used such that it only has at most one permit available, can serve as a mutual exclusion lock. This is more commonly known as a binary semaphore, because it only has two states: one permit available, or zero permits available. When used in this way, the binary semaphore has the property (unlike many Lock implementations), that the <em><strong>\"lock\" can be released by a thread other than the owner (as semaphores have no notion of ownership). This can be useful in some specialized contexts, such as deadlock recovery<\/strong><\/em>.<\/p>\n<pre lang=\"java\">\r\nclass FooBar {\r\n    private int n;\r\n    private final Semaphore mutexFoo = new Semaphore(1);\r\n    private final Semaphore mutexBar = new Semaphore(1);\r\n\r\n    public FooBar(int n) {\r\n        this.n = n;\r\n        try {\r\n            mutexBar.acquire();\r\n        } catch ( Exception e ) {}\r\n    }\r\n\r\n    public void foo(Runnable printFoo) throws InterruptedException {\r\n        \r\n        for (int i = 0; i < n; i++) {\r\n                        \r\n            \/\/ printFoo.run() outputs \"foo\". Do not change or remove this line.\r\n            mutexFoo.acquire();\r\n            printFoo.run();\r\n            mutexBar.release();\r\n        }\r\n    }\r\n\r\n    public void bar(Runnable printBar) throws InterruptedException {\r\n        \r\n        for (int i = 0; i < n; i++) {     \r\n            \/\/ printBar.run() outputs \"bar\". Do not change or remove this line.\r\n            mutexBar.acquire();\r\n            printBar.run();\r\n            mutexFoo.release();\r\n        }\r\n    }\r\n}\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Suppose you are given the following code: class FooBar { public void foo() { for (int i = 0; i < n; i++) { print(\"foo\"); } } public void bar() { for (int i = 0; i < n; i++) { print(\"bar\"); } } } The same instance of FooBar will be passed to two [&hellip;]\n<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-11398","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/www.softwareeverydayblog.com\/index.php?rest_route=\/wp\/v2\/posts\/11398","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.softwareeverydayblog.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.softwareeverydayblog.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.softwareeverydayblog.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.softwareeverydayblog.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=11398"}],"version-history":[{"count":5,"href":"https:\/\/www.softwareeverydayblog.com\/index.php?rest_route=\/wp\/v2\/posts\/11398\/revisions"}],"predecessor-version":[{"id":11400,"href":"https:\/\/www.softwareeverydayblog.com\/index.php?rest_route=\/wp\/v2\/posts\/11398\/revisions\/11400"}],"wp:attachment":[{"href":"https:\/\/www.softwareeverydayblog.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=11398"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.softwareeverydayblog.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=11398"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.softwareeverydayblog.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=11398"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}