Last active
September 21, 2020 05:52
-
-
Save Neko3000/99488af93758d43f04ecfc3e863873f6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
extension Thread{ | |
public func join(){ | |
while(!self.isFinished){ | |
usleep(10) | |
} | |
} | |
public func state() -> String{ | |
var state: String = "" | |
if(self.isExecuting){ | |
state = "isExecuting" | |
} | |
else if(self.isFinished){ | |
state = "isFinished" | |
} | |
else if(self.isCancelled){ | |
state = "isCancelled" | |
} | |
return state | |
} | |
} | |
class TestUnitA: NSObject{ | |
var thread1 : Thread? | |
var thread2 : Thread? | |
override init() { | |
super.init() | |
} | |
@objc func threadProc(){ | |
print("\nCurrent thread: \(Thread.current.name ?? "none") started"); | |
for i in 1...10{ | |
if (Thread.current.name == "Thread1"){ | |
if(self.thread2 != nil && self.thread2!.isExecuting){ | |
thread2!.join(); | |
} | |
} | |
print("Current thread: \(Thread.current.name ?? "none") outputs \(i)") | |
sleep(1) | |
} | |
usleep(10) | |
print("Current thread: \(Thread.current.name ?? "none") after loop"); | |
print("Thread1: \(thread1!.state())"); | |
print("Thread2: \(thread2!.state())"); | |
print("Current thread: \(Thread.current.name ?? "none") finished\n"); | |
} | |
public func run(){ | |
self.thread1 = Thread(target: self, selector: #selector(threadProc), object: nil) | |
thread1!.name = "Thread1" | |
thread1!.start() | |
sleep(5) | |
self.thread2 = Thread(target: self, selector: #selector(threadProc), object: nil) | |
thread2!.name = "Thread2" | |
thread2!.start() | |
} | |
} | |
let testUnit = TestUnitA() | |
testUnit.run() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
class JoinableThread: NSObject{ | |
public var name:String? | |
public var isExecuting:Bool{ | |
return self.thread!.isExecuting | |
} | |
public var isCancelled:Bool{ | |
return self.thread!.isCancelled | |
} | |
public var isFinished:Bool{ | |
return self.thread!.isFinished | |
} | |
private var thread:Thread? | |
private var target:AnyObject? | |
private var selector:Selector? | |
private var arguments:AnyObject? | |
private let runLoopMode:RunLoop.Mode = RunLoop.Mode.init(rawValue: "joinMe") | |
init(target:AnyObject ,selector:Selector, arguments:AnyObject?) { | |
super.init() | |
self.thread = Thread(target: self, selector: #selector(beforeTask), object: nil) | |
self.target = target | |
self.selector = selector | |
self.arguments = arguments | |
} | |
@objc public func beforeTask() { | |
if(self.thread!.isCancelled){ | |
return | |
} | |
// ???: 这步让我疑惑,在iOS7.0+,似乎线程一开始以后就自动创建了autoreleasepool | |
// https://stackoverflow.com/questions/24952549/does-nsthread-create-autoreleasepool-automatically-now | |
autoreleasepool{ | |
Thread.current.name = self.name | |
autoreleasepool{ | |
if(self.target!.responds(to: self.selector!)){ | |
self.target!.perform(self.selector!, with: arguments ?? nil) | |
} | |
} | |
RunLoop.current.add(Port(), forMode: self.runLoopMode) | |
RunLoop.current.run(mode: self.runLoopMode, before: Date.distantFuture) | |
} | |
} | |
@objc public func finishJoin(){ | |
print("join finished"); | |
} | |
public func join() -> Bool{ | |
if(!self.thread!.isFinished){ | |
self.perform(#selector(finishJoin), on: self.thread!, with: nil, waitUntilDone: true, modes: [self.runLoopMode.rawValue]) | |
return true | |
} | |
return false | |
} | |
public func start(){ | |
self.thread!.start() | |
} | |
public func state() -> String{ | |
var state: String = "" | |
if(self.thread!.isExecuting){ | |
state = "isExecuting" | |
} | |
else if(self.thread!.isFinished){ | |
state = "isFinished" | |
} | |
else if(self.thread!.isCancelled){ | |
state = "isCancelled" | |
} | |
return state | |
} | |
} | |
class TestUnitB: NSObject{ | |
var joinableThread1 : JoinableThread? | |
var joinableThread2 : JoinableThread? | |
override init() { | |
super.init() | |
} | |
@objc func threadProc(){ | |
print("\nCurrent thread: \(Thread.current.name ?? "none") started"); | |
for i in 1...10{ | |
if (Thread.current.name == "Thread1"){ | |
if(self.joinableThread2 != nil && self.joinableThread2!.isExecuting){ | |
joinableThread2!.join(); | |
} | |
} | |
print("Current thread: \(Thread.current.name ?? "none") outputs \(i)") | |
sleep(1) | |
} | |
usleep(10) | |
print("Current thread: \(Thread.current.name ?? "none") after loop"); | |
print("Thread1: \(joinableThread1!.state())"); | |
print("Thread2: \(joinableThread2!.state())"); | |
print("Current thread: \(Thread.current.name ?? "none") finished\n"); | |
} | |
public func run(){ | |
self.joinableThread1 = JoinableThread(target: self, selector: #selector(threadProc), arguments: nil) | |
joinableThread1!.name = "Thread1" | |
joinableThread1!.start() | |
sleep(5) | |
self.joinableThread2 = JoinableThread(target: self, selector: #selector(threadProc), arguments: nil) | |
joinableThread2!.name = "Thread2" | |
joinableThread2!.start() | |
} | |
} | |
let testUnit = TestUnitB() | |
testUnit.run() | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
for (;![self.thread isFinished];) { | |
// 要是没结束就休眠!! | |
usleep(2); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Threading; | |
public class Example | |
{ | |
static Thread thread1, thread2; | |
public static void Main() | |
{ | |
thread1 = new Thread(ThreadProc); | |
thread1.Name = "Thread1"; | |
thread1.Start(); | |
thread2 = new Thread(ThreadProc); | |
thread2.Name = "Thread2"; | |
thread2.Start(); | |
} | |
private static void ThreadProc() | |
{ | |
Console.WriteLine("\nCurrent thread: {0}", Thread.CurrentThread.Name); | |
if (Thread.CurrentThread.Name == "Thread1" && | |
thread2.ThreadState != ThreadState.Unstarted) | |
thread2.Join(); | |
Thread.Sleep(4000); | |
Console.WriteLine("\nCurrent thread: {0}", Thread.CurrentThread.Name); | |
Console.WriteLine("Thread1: {0}", thread1.ThreadState); | |
Console.WriteLine("Thread2: {0}\n", thread2.ThreadState); | |
} | |
} | |
// The example displays output like the following: | |
// Current thread: Thread1 | |
// | |
// Current thread: Thread2 | |
// | |
// Current thread: Thread2 | |
// Thread1: WaitSleepJoin | |
// Thread2: Running | |
// | |
// | |
// Current thread: Thread1 | |
// Thread1: Running | |
// Thread2: Stopped |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment