{ "data": { "question": { "questionId": "1203", "questionFrontendId": "1114", "categoryTitle": "Concurrency", "boundTopicId": 13757, "title": "Print in Order", "titleSlug": "print-in-order", "content": "

Suppose we have a class:

\n\n
\npublic class Foo {\n  public void first() { print("first"); }\n  public void second() { print("second"); }\n  public void third() { print("third"); }\n}\n
\n\n

The same instance of Foo will be passed to three different threads. Thread A will call first(), thread B will call second(), and thread C will call third(). Design a mechanism and modify the program to ensure that second() is executed after first(), and third() is executed after second().

\n\n

Note:

\n\n

We do not know how the threads will be scheduled in the operating system, even though the numbers in the input seem to imply the ordering. The input format you see is mainly to ensure our tests' comprehensiveness.

\n\n

 

\n

Example 1:

\n\n
\nInput: nums = [1,2,3]\nOutput: "firstsecondthird"\nExplanation: There are three threads being fired asynchronously. The input [1,2,3] means thread A calls first(), thread B calls second(), and thread C calls third(). "firstsecondthird" is the correct output.\n
\n\n

Example 2:

\n\n
\nInput: nums = [1,3,2]\nOutput: "firstsecondthird"\nExplanation: The input [1,3,2] means thread A calls first(), thread B calls third(), and thread C calls second(). "firstsecondthird" is the correct output.\n
\n\n

 

\n

Constraints:

\n\n\n", "translatedTitle": "按序打印", "translatedContent": "

给你一个类:

\n\n
\npublic class Foo {\n  public void first() { print(\"first\"); }\n  public void second() { print(\"second\"); }\n  public void third() { print(\"third\"); }\n}
\n\n

三个不同的线程 A、B、C 将会共用一个 Foo 实例。

\n\n\n\n

请设计修改程序,以确保 second() 方法在 first() 方法之后被执行,third() 方法在 second() 方法之后被执行。

\n\n

提示:

\n\n\n\n

 

\n\n

示例 1:

\n\n
\n输入:nums = [1,2,3]\n输出:\"firstsecondthird\"\n解释:\n有三个线程会被异步启动。输入 [1,2,3] 表示线程 A 将会调用 first() 方法,线程 B 将会调用 second() 方法,线程 C 将会调用 third() 方法。正确的输出是 \"firstsecondthird\"。\n
\n\n

示例 2:

\n\n
\n输入:nums = [1,3,2]\n输出:\"firstsecondthird\"\n解释:\n输入 [1,3,2] 表示线程 A 将会调用 first() 方法,线程 B 将会调用 third() 方法,线程 C 将会调用 second() 方法。正确的输出是 \"firstsecondthird\"。
\n\n

 

\n\n\n提示:\n\n\n", "isPaidOnly": false, "difficulty": "Easy", "likes": 375, "dislikes": 0, "isLiked": null, "similarQuestions": "[{\"title\": \"Print FooBar Alternately\", \"titleSlug\": \"print-foobar-alternately\", \"difficulty\": \"Medium\", \"translatedTitle\": \"\\u4ea4\\u66ff\\u6253\\u5370 FooBar\"}]", "contributors": [], "langToValidPlayground": "{\"cpp\": true, \"java\": true, \"python\": true, \"python3\": true, \"mysql\": false, \"mssql\": false, \"oraclesql\": false, \"c\": false, \"csharp\": false, \"javascript\": false, \"ruby\": false, \"bash\": false, \"swift\": false, \"golang\": false, \"scala\": false, \"html\": false, \"pythonml\": false, \"kotlin\": false, \"rust\": false, \"php\": false, \"typescript\": false, \"racket\": false, \"erlang\": false, \"elixir\": false}", "topicTags": [ { "name": "Concurrency", "slug": "concurrency", "translatedName": "多线程", "__typename": "TopicTagNode" } ], "companyTagStats": null, "codeSnippets": [ { "lang": "C++", "langSlug": "cpp", "code": "class Foo {\npublic:\n Foo() {\n \n }\n\n void first(function printFirst) {\n \n // printFirst() outputs \"first\". Do not change or remove this line.\n printFirst();\n }\n\n void second(function printSecond) {\n \n // printSecond() outputs \"second\". Do not change or remove this line.\n printSecond();\n }\n\n void third(function printThird) {\n \n // printThird() outputs \"third\". Do not change or remove this line.\n printThird();\n }\n};", "__typename": "CodeSnippetNode" }, { "lang": "Java", "langSlug": "java", "code": "class Foo {\n\n public Foo() {\n \n }\n\n public void first(Runnable printFirst) throws InterruptedException {\n \n // printFirst.run() outputs \"first\". Do not change or remove this line.\n printFirst.run();\n }\n\n public void second(Runnable printSecond) throws InterruptedException {\n \n // printSecond.run() outputs \"second\". Do not change or remove this line.\n printSecond.run();\n }\n\n public void third(Runnable printThird) throws InterruptedException {\n \n // printThird.run() outputs \"third\". Do not change or remove this line.\n printThird.run();\n }\n}", "__typename": "CodeSnippetNode" }, { "lang": "Python", "langSlug": "python", "code": "class Foo(object):\n def __init__(self):\n pass\n\n\n def first(self, printFirst):\n \"\"\"\n :type printFirst: method\n :rtype: void\n \"\"\"\n \n # printFirst() outputs \"first\". Do not change or remove this line.\n printFirst()\n\n\n def second(self, printSecond):\n \"\"\"\n :type printSecond: method\n :rtype: void\n \"\"\"\n \n # printSecond() outputs \"second\". Do not change or remove this line.\n printSecond()\n \n \n def third(self, printThird):\n \"\"\"\n :type printThird: method\n :rtype: void\n \"\"\"\n \n # printThird() outputs \"third\". Do not change or remove this line.\n printThird()", "__typename": "CodeSnippetNode" }, { "lang": "Python3", "langSlug": "python3", "code": "class Foo:\n def __init__(self):\n pass\n\n\n def first(self, printFirst: 'Callable[[], None]') -> None:\n \n # printFirst() outputs \"first\". Do not change or remove this line.\n printFirst()\n\n\n def second(self, printSecond: 'Callable[[], None]') -> None:\n \n # printSecond() outputs \"second\". Do not change or remove this line.\n printSecond()\n\n\n def third(self, printThird: 'Callable[[], None]') -> None:\n \n # printThird() outputs \"third\". Do not change or remove this line.\n printThird()", "__typename": "CodeSnippetNode" }, { "lang": "C", "langSlug": "c", "code": "typedef struct {\n // User defined data may be declared here.\n \n} Foo;\n\nFoo* fooCreate() {\n Foo* obj = (Foo*) malloc(sizeof(Foo));\n \n // Initialize user defined data here.\n \n return obj;\n}\n\nvoid first(Foo* obj) {\n \n // printFirst() outputs \"first\". Do not change or remove this line.\n printFirst();\n}\n\nvoid second(Foo* obj) {\n \n // printSecond() outputs \"second\". Do not change or remove this line.\n printSecond();\n}\n\nvoid third(Foo* obj) {\n \n // printThird() outputs \"third\". Do not change or remove this line.\n printThird();\n}\n\nvoid fooFree(Foo* obj) {\n // User defined data may be cleaned up here.\n \n}", "__typename": "CodeSnippetNode" }, { "lang": "C#", "langSlug": "csharp", "code": "public class Foo {\n\n public Foo() {\n \n }\n\n public void First(Action printFirst) {\n \n // printFirst() outputs \"first\". Do not change or remove this line.\n printFirst();\n }\n\n public void Second(Action printSecond) {\n \n // printSecond() outputs \"second\". Do not change or remove this line.\n printSecond();\n }\n\n public void Third(Action printThird) {\n \n // printThird() outputs \"third\". Do not change or remove this line.\n printThird();\n }\n}", "__typename": "CodeSnippetNode" } ], "stats": "{\"totalAccepted\": \"88.1K\", \"totalSubmission\": \"135K\", \"totalAcceptedRaw\": 88138, \"totalSubmissionRaw\": 135002, \"acRate\": \"65.3%\"}", "hints": [], "solution": null, "status": null, "sampleTestCase": "[1,2,3]", "metaData": "{\n \"name\": \"foobar\",\n \"params\": [\n {\n \"name\": \"nums\",\n \"type\": \"integer[]\"\n }\n ],\n \"return\": {\n \"type\": \"integer\"\n },\n \"languages\": [\n \"java\",\n \"cpp\",\n \"python\",\n \"python3\",\n \"c\",\n \"csharp\"\n ],\n \"manual\": true\n}", "judgerAvailable": true, "judgeType": "large", "mysqlSchemas": [], "enableRunCode": true, "envInfo": "{\"cpp\":[\"C++\",\"

\\u7248\\u672c\\uff1aclang 11<\\/code> \\u91c7\\u7528\\u6700\\u65b0C++ 17\\u6807\\u51c6\\u3002<\\/p>\\r\\n\\r\\n

\\u7f16\\u8bd1\\u65f6\\uff0c\\u5c06\\u4f1a\\u91c7\\u7528-O2<\\/code>\\u7ea7\\u4f18\\u5316\\u3002AddressSanitizer<\\/a> \\u4e5f\\u88ab\\u5f00\\u542f\\u6765\\u68c0\\u6d4bout-of-bounds<\\/code>\\u548cuse-after-free<\\/code>\\u9519\\u8bef\\u3002<\\/p>\\r\\n\\r\\n

\\u4e3a\\u4e86\\u4f7f\\u7528\\u65b9\\u4fbf\\uff0c\\u5927\\u90e8\\u5206\\u6807\\u51c6\\u5e93\\u7684\\u5934\\u6587\\u4ef6\\u5df2\\u7ecf\\u88ab\\u81ea\\u52a8\\u5bfc\\u5165\\u3002<\\/p>\"],\"java\":[\"Java\",\"

\\u7248\\u672c\\uff1aOpenJDK 17<\\/code>\\u3002\\u53ef\\u4ee5\\u4f7f\\u7528Java 8\\u7684\\u7279\\u6027\\u4f8b\\u5982\\uff0clambda expressions \\u548c stream API\\u3002<\\/p>\\r\\n\\r\\n

\\u4e3a\\u4e86\\u65b9\\u4fbf\\u8d77\\u89c1\\uff0c\\u5927\\u90e8\\u5206\\u6807\\u51c6\\u5e93\\u7684\\u5934\\u6587\\u4ef6\\u5df2\\u88ab\\u5bfc\\u5165\\u3002<\\/p>\\r\\n\\r\\n

\\u5305\\u542b Pair \\u7c7b: https:\\/\\/docs.oracle.com\\/javase\\/8\\/javafx\\/api\\/javafx\\/util\\/Pair.html <\\/p>\"],\"python\":[\"Python\",\"

\\u7248\\u672c\\uff1a Python 2.7.12<\\/code><\\/p>\\r\\n\\r\\n

\\u4e3a\\u4e86\\u65b9\\u4fbf\\u8d77\\u89c1\\uff0c\\u5927\\u90e8\\u5206\\u5e38\\u7528\\u5e93\\u5df2\\u7ecf\\u88ab\\u81ea\\u52a8 \\u5bfc\\u5165\\uff0c\\u5982\\uff1aarray<\\/a>, bisect<\\/a>, collections<\\/a>\\u3002\\u5982\\u679c\\u60a8\\u9700\\u8981\\u4f7f\\u7528\\u5176\\u4ed6\\u5e93\\u51fd\\u6570\\uff0c\\u8bf7\\u81ea\\u884c\\u5bfc\\u5165\\u3002<\\/p>\\r\\n\\r\\n

\\u6ce8\\u610f Python 2.7 \\u5c06\\u57282020\\u5e74\\u540e\\u4e0d\\u518d\\u7ef4\\u62a4<\\/a>\\u3002 \\u5982\\u60f3\\u4f7f\\u7528\\u6700\\u65b0\\u7248\\u7684Python\\uff0c\\u8bf7\\u9009\\u62e9Python 3\\u3002<\\/p>\"],\"c\":[\"C\",\"

\\u7248\\u672c\\uff1aGCC 8.2<\\/code>\\uff0c\\u91c7\\u7528GNU99\\u6807\\u51c6\\u3002<\\/p>\\r\\n\\r\\n

\\u7f16\\u8bd1\\u65f6\\uff0c\\u5c06\\u4f1a\\u91c7\\u7528-O1<\\/code>\\u7ea7\\u4f18\\u5316\\u3002 AddressSanitizer<\\/a>\\u4e5f\\u88ab\\u5f00\\u542f\\u6765\\u68c0\\u6d4bout-of-bounds<\\/code>\\u548cuse-after-free<\\/code>\\u9519\\u8bef\\u3002<\\/p>\\r\\n\\r\\n

\\u4e3a\\u4e86\\u4f7f\\u7528\\u65b9\\u4fbf\\uff0c\\u5927\\u90e8\\u5206\\u6807\\u51c6\\u5e93\\u7684\\u5934\\u6587\\u4ef6\\u5df2\\u7ecf\\u88ab\\u81ea\\u52a8\\u5bfc\\u5165\\u3002<\\/p>\\r\\n\\r\\n

\\u5982\\u60f3\\u4f7f\\u7528\\u54c8\\u5e0c\\u8868\\u8fd0\\u7b97, \\u60a8\\u53ef\\u4ee5\\u4f7f\\u7528 uthash<\\/a>\\u3002 \\\"uthash.h\\\"\\u5df2\\u7ecf\\u9ed8\\u8ba4\\u88ab\\u5bfc\\u5165\\u3002\\u8bf7\\u770b\\u5982\\u4e0b\\u793a\\u4f8b:<\\/p>\\r\\n\\r\\n

1. \\u5f80\\u54c8\\u5e0c\\u8868\\u4e2d\\u6dfb\\u52a0\\u4e00\\u4e2a\\u5bf9\\u8c61\\uff1a<\\/b>\\r\\n

\\r\\nstruct hash_entry {\\r\\n    int id;            \\/* we'll use this field as the key *\\/\\r\\n    char name[10];\\r\\n    UT_hash_handle hh; \\/* makes this structure hashable *\\/\\r\\n};\\r\\n\\r\\nstruct hash_entry *users = NULL;\\r\\n\\r\\nvoid add_user(struct hash_entry *s) {\\r\\n    HASH_ADD_INT(users, id, s);\\r\\n}\\r\\n<\\/pre>\\r\\n<\\/p>\\r\\n\\r\\n

2. \\u5728\\u54c8\\u5e0c\\u8868\\u4e2d\\u67e5\\u627e\\u4e00\\u4e2a\\u5bf9\\u8c61\\uff1a<\\/b>\\r\\n

\\r\\nstruct hash_entry *find_user(int user_id) {\\r\\n    struct hash_entry *s;\\r\\n    HASH_FIND_INT(users, &user_id, s);\\r\\n    return s;\\r\\n}\\r\\n<\\/pre>\\r\\n<\\/p>\\r\\n\\r\\n

3. \\u4ece\\u54c8\\u5e0c\\u8868\\u4e2d\\u5220\\u9664\\u4e00\\u4e2a\\u5bf9\\u8c61\\uff1a<\\/b>\\r\\n

\\r\\nvoid delete_user(struct hash_entry *user) {\\r\\n    HASH_DEL(users, user);  \\r\\n}\\r\\n<\\/pre>\\r\\n<\\/p>\"],\"csharp\":[\"C#\",\"

C# 10<\\/a> \\u8fd0\\u884c\\u5728 .NET 6 \\u4e0a<\\/p>\\r\\n\\r\\n

\\u60a8\\u7684\\u4ee3\\u7801\\u5728\\u7f16\\u8bd1\\u65f6\\u9ed8\\u8ba4\\u5f00\\u542f\\u4e86debug\\u6807\\u8bb0(\\/debug:pdbonly<\\/code>)\\u3002<\\/p>\"],\"python3\":[\"Python3\",\"

\\u7248\\u672c\\uff1aPython 3.10<\\/code><\\/p>\\r\\n\\r\\n

\\u4e3a\\u4e86\\u65b9\\u4fbf\\u8d77\\u89c1\\uff0c\\u5927\\u90e8\\u5206\\u5e38\\u7528\\u5e93\\u5df2\\u7ecf\\u88ab\\u81ea\\u52a8 \\u5bfc\\u5165\\uff0c\\u5982array<\\/a>, bisect<\\/a>, collections<\\/a>\\u3002 \\u5982\\u679c\\u60a8\\u9700\\u8981\\u4f7f\\u7528\\u5176\\u4ed6\\u5e93\\u51fd\\u6570\\uff0c\\u8bf7\\u81ea\\u884c\\u5bfc\\u5165\\u3002<\\/p>\\r\\n\\r\\n

\\u5982\\u9700\\u4f7f\\u7528 Map\\/TreeMap \\u6570\\u636e\\u7ed3\\u6784\\uff0c\\u60a8\\u53ef\\u4f7f\\u7528 sortedcontainers<\\/a> \\u5e93\\u3002<\\/p>\"]}", "book": null, "isSubscribed": false, "isDailyQuestion": false, "dailyRecordStatus": null, "editorType": "CKEDITOR", "ugcQuestionId": null, "style": "LEETCODE", "exampleTestcases": "[1,2,3]\n[1,3,2]", "__typename": "QuestionNode" } } }