TShopping
標題:
由Android Looper的實現引發的基礎補習
[打印本頁]
作者:
woff
時間:
2017-8-24 15:19
標題:
由Android Looper的實現引發的基礎補習
Android的Looper只允許一個線程中有且只有一個Looper,具體實現使用了ThreadLocal來達到這個目的,如果要在新的線程中進行消息傳遞,則必須調用Looper的靜態方法prepare()
public class Looper {
// 每个线程中的Looper对象其实是一个ThreadLocal,即线程本地存储(TLS)对象
private static final ThreadLocal sThreadLocal = new ThreadLocal();
// Looper内的消息队列
final MessageQueue mQueue;
// 当前线程
Thread mThread;
// 。。。其他属性
// 每个Looper对象中有它的消息队列,和它所属的线程
private Looper() {
mQueue = new MessageQueue();
mRun = true;
mThread = Thread.currentThread();
}
// 我们调用该方法会在调用线程的TLS中创建Looper对象
public static final void prepare() {
if (sThreadLocal.get() != null) {
// 试图在有Looper的线程中再次创建Looper将抛出异常
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper());
}
// 其他方法
}
複製代碼
於是在想,類變量如果是static的(比如int,初始為0),在main和子線程中各創建一個實例後打印這個int值,到底是怎麼樣的呢(大家有時有沒有同樣的感覺,可能以前真沒想到這麼多,或者突然之間質疑自己以前以為的結論?)
class Program
{
static void Main(string[] args)
{
Entity entity = new Entity();
entity.Print();
new Thread(t => { Entity e = new Entity(); e.Print(); }).Start();
new Thread(t => { Entity e = new Entity(); e.Print(); }).Start();
Entity entity2 = new Entity();
entity2.Print();
Entity entity3 = new Entity();
entity3.Print();
Console.Read();
}
}
public class Entity
{
private static int count = 0;
public Entity()
{
count++;
}
public void Print()
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId+ ":" + count);
}
}
複製代碼
輸出:
9:1
9:2
9:3
10:4
11:5
如果替換成ThreadLocal又會是怎麼樣的呢
class Program
{
static void Main(string[] args)
{
Entity entity = new Entity();
entity.Print();
new Thread(t => { Entity e = new Entity(); e.Print(); }).Start();
new Thread(t => { Entity e = new Entity(); e.Print(); }).Start();
Entity entity2 = new Entity();
entity2.Print();
Entity entity3 = new Entity();
entity3.Print();
Console.Read();
}
}
public class Entity
{
private static ThreadLocal<int> threadLocal = new ThreadLocal<int>();
public Entity()
{
if (threadLocal.IsValueCreated)
{
threadLocal.Value = threadLocal.Value + 1;
}
else
{
threadLocal.Value = 0;
}
}
public void Print()
{
//Console.WriteLine(Thread.CurrentThread.ManagedThreadId+ ":" + count);
Console.WriteLine(Thread.CurrentThread.ManagedThreadId + ":" + threadLocal.Value);
}
}
複製代碼
輸出
9:0
9:1
9:2
10:0
11:0
可見不同線程中的值各有一個副本,同一線程中類似於上例中的結果(純Static)。
歡迎光臨 TShopping (http://www.tshopping.com.tw/)
Powered by Discuz! X3.2