Android多线程研究(1)——线程基础及源码剖析
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                Android多线程研究(1)——线程基础及源码剖析
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.                        
                                從今天起我們來看一下Android中的多線程的知識,Android入門容易,但是要完成一個完善的產品卻不容易,讓我們從線程開始一步步深入Android內部。
一、線程基礎回顧
package com.maso.test;public class TraditionalThread {public static void main(String[] args) {/** 線程的第一種創建方式*/Thread thread1 = new Thread(){@Overridepublic void run() {try {sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}while(true){System.out.println(Thread.currentThread().getName());}}};thread1.start();/**線程的第二種創建方式 */Thread thread2 = new Thread(new Runnable() {@Overridepublic void run() {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}while (true) {System.out.println(Thread.currentThread().getName());}}});thread2.start();/** 線程的調用優先級*/new Thread(new Runnable() {@Overridepublic void run() {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}while(true){System.out.println("Runnable");}}}){public void run() {try {sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}while(true){System.out.println("Thread");}};}.start();} } 上面代碼中是我們都很熟悉的線程的兩種創建方式,如果對這些還感到陌生請先看Java線程基礎。打開Thread類的源碼可以看到Thread類有8個構造函數,我們先看看上面的兩種構造函數的源碼。
public Thread() {init(null, null, "Thread-" + nextThreadNum(), 0);}在構造的時候直接調用了init方法 private void init(ThreadGroup g, Runnable target, String name,long stackSize) {if (name == null) {throw new NullPointerException("name cannot be null");}Thread parent = currentThread();SecurityManager security = System.getSecurityManager();if (g == null) {/* Determine if it's an applet or not *//* If there is a security manager, ask the security managerwhat to do. */if (security != null) {g = security.getThreadGroup();}/* If the security doesn't have a strong opinion of the matteruse the parent thread group. */if (g == null) {g = parent.getThreadGroup();}}/* checkAccess regardless of whether or not threadgroup isexplicitly passed in. */g.checkAccess();/** Do we have the required permissions?*/if (security != null) {if (isCCLOverridden(getClass())) {security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);}}g.addUnstarted();this.group = g;this.daemon = parent.isDaemon();this.priority = parent.getPriority();this.name = name.toCharArray();if (security == null || isCCLOverridden(parent.getClass()))this.contextClassLoader = parent.getContextClassLoader();elsethis.contextClassLoader = parent.contextClassLoader;this.inheritedAccessControlContext = AccessController.getContext();this.target = target;setPriority(priority);if (parent.inheritableThreadLocals != null)this.inheritableThreadLocals =ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);/* Stash the specified stack size in case the VM cares */this.stackSize = stackSize;/* Set thread ID */tid = nextThreadID();} 里面的東西比較多,但是我們可以看到會初始化一個變量Runnable ?target;下面我們再來看看run方法中是個什么東東?
@Overridepublic void run() {if (target != null) {target.run();}}原來run方法中會先判斷是否初始化了Runnable target變量,如果沒有則空實現,如果target不為空則先執行Runnable接口中的run方法。有的朋友可能會猜想下面的代碼會先調用Runnable接口中的run方法,然后才調用Thread實現類中的run方法。 /** 線程的調用優先級*/new Thread(new Runnable() {@Overridepublic void run() {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}while(true){System.out.println("Runnable");}}}){public void run() {try {sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}while(true){System.out.println("Thread");}};}.start();其實事實并非如此,因為上面代碼中是一個匿名內部類,實際上是一種從Thread的繼承和實現,所以下面的run方法覆蓋了Thread中的run方法,所以Runnable中的run方法根本不會執行。下面再看看Runnable接口的源代碼
public interface Runnable {/*** When an object implementing interface <code>Runnable</code> is used* to create a thread, starting the thread causes the object's* <code>run</code> method to be called in that separately executing* thread.* <p>* The general contract of the method <code>run</code> is that it may* take any action whatsoever.** @see java.lang.Thread#run()*/public abstract void run(); } 發現Runnable接口只有一個抽象的run方法。為什么要搞一個Runnable接口來實現多線程呢?從Thread繼承不是更方便嗎?Runnable接口有如下優勢,所以我們常常會選擇實現Runnable接口:
1、適合多個程序代碼的線程去處理同一個資源。
public class ThreadTest1 extends Thread {private int count = 5;public void run() {for (int i = 0; i < 7; i++) {if (count > 0) {System.out.println("count= " + count--);}}}public static void main(String[] args) {//這樣實際上是創建了三個互不影響的線程實例ThreadTest1 t1 = new ThreadTest1();ThreadTest1 t2 = new ThreadTest1();ThreadTest1 t3 = new ThreadTest1();t1.start();t2.start();t3.start();} }public class ThreadTest1{public static void main(String [] args) {MyThread my = new MyThread();//開啟了三個線程,但是操作的是同一個run方法new Thread(my, "1號窗口").start();new Thread(my, "2號窗口").start();new Thread(my, "3號窗口").start();} }class MyThread implements Runnable{private int ticket = 5; //5張票public void run() {for (int i=0; i<=20; i++) {if (this.ticket > 0) {System.out.println(Thread.currentThread().getName()+ "正在賣票"+this.ticket--);}}} }2、避免Java特性中的單根繼承的限制。
3、可以保持代碼和數據的分離(創建線程數和數據無關)。
4、更能體現Java面向對象的設計特點。
轉載于:https://www.cnblogs.com/lanzhi/p/6468951.html
總結
以上是生活随笔為你收集整理的Android多线程研究(1)——线程基础及源码剖析的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: DOCTYPE html PUBLIC
- 下一篇: 【7】AccessDB快速数据访问
