中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

政府網(wǎng)站建設(shè)培訓(xùn)講話惠州優(yōu)化怎么做seo

政府網(wǎng)站建設(shè)培訓(xùn)講話,惠州優(yōu)化怎么做seo,云渲染網(wǎng)站開發(fā),學(xué)做內(nèi)賬的網(wǎng)站第六章:多線程 6.1:程序、進程、線程基本概念 程序 程序program是為了完成特定任務(wù)、用某種語言編寫的一組指令的集合。即指一段靜態(tài)的代碼,靜態(tài)對象。 進程 ? 進程process是程序的一次執(zhí)行過程,或是正在運行的一個程序。是一個…

第六章:多線程

6.1:程序、進程、線程基本概念

  1. 程序

    程序program是為了完成特定任務(wù)、用某種語言編寫的一組指令的集合。即指一段靜態(tài)的代碼,靜態(tài)對象。

  2. 進程

    ? 進程process是程序的一次執(zhí)行過程,或是正在運行的一個程序。是一個動態(tài)的過程:有它自身的產(chǎn)生、存在和消亡的過程?!旧芷凇?/p>

    • 程序是靜態(tài)的,進程是動態(tài)的。
    • 進程作為資源分配的單位,系統(tǒng)在運行時會為每個進程分配不同的內(nèi)存區(qū)域。
  3. 線程

    進程可進一步細化為線程,是一個程序內(nèi)部的一條執(zhí)行路徑。

    • 若一個進行同一時間并行執(zhí)行多個線程,就是支持多線程的。
    • 線程作為調(diào)度和執(zhí)行的單位,每個線程擁有獨立的運行棧和程序計數(shù)器(pc),線程切換的開銷小。
    • 一個進程中的多個線程共享相同的內(nèi)存單元/內(nèi)存地址空間。他們從同一堆中分配對象,可以訪問相同的變量和對象。這就使得線程間通信更簡便、高效。但是多個線程操作共享的系統(tǒng)資源可能就會帶來安全的隱患。
  4. 單核CPU和多核CPU的理解

    • 單核CPU,其實是一種假的多線程,因為在一個時間單元內(nèi),也只能執(zhí)行一個線程的任務(wù)。
    • 如果是多核的話,才能更好的發(fā)揮多線程的效率。
    • 一個Java應(yīng)用程序java.exe,其實至少有三個線程。main()主線程gc()垃圾回收線程、異常處理線程。
  5. 并行與并發(fā)

    • 并行:多個CPU同時執(zhí)行多個任務(wù)。

    • 并發(fā):一個CPU(采用時間片)同時執(zhí)行多個任務(wù)。

  6. 使用多線程的優(yōu)點

    • 提高應(yīng)用程序的響應(yīng)。對圖形化界面更有意義,可增強用戶體驗。
    • 提供計算機系統(tǒng)CPU的利用率。
    • 改善程序結(jié)構(gòu)。將既長又復(fù)雜的進程分為多個線程,獨立運行,利于理解和修改。
  7. 何時需要多線程

    • 程序需要同時執(zhí)行兩個或多個任務(wù)。
    • 程序需要實現(xiàn)一些需要等待的任務(wù)時,如用戶輸入、文件讀寫操作、網(wǎng)絡(luò)操作、搜索等。
    • 需要一些后臺運行的程序時。

6.2:線程的創(chuàng)建和使用

? Java語言的JVM允許程序運行多個線程,它通過java.lang.Thread類來體現(xiàn)。

  1. Thread類的特性

    • 每個線程都是通過某個特定Thread對象的run()方法來完成操作的,經(jīng)常把run()方法的主體稱為線程體。
    • 通過該Thread對象的start()方法來啟動這個線程,而非直接調(diào)用run()。
  2. Thread類的構(gòu)造器

    • Thread():創(chuàng)建新的Thread對象
    • Thread(String threadname):創(chuàng)建線程并指定線程實例名。
    • Thread(Runnable target):指定創(chuàng)建線程的目標(biāo)對象,它實現(xiàn)了Runnable接口中的run方法。
    • Thread(Runnable target, String name):創(chuàng)建新的Thread對象。
  3. 多線程的創(chuàng)建一:繼承Thread

    • 創(chuàng)建一個繼承與Thread類的子類。
    • 重寫Thread類的run() ----> 將此線程執(zhí)行的操作聲明在run()中。
    • 創(chuàng)建Thread類的子類的對象。
    • 通過此對象調(diào)用start()。
    // 1.創(chuàng)建一個繼承與Thread類的子類。
    class MyThread extends Thread{// 2.重寫Thread類的run()  public void run() {for(int i = 0; i < 100; i++) {if(i % 2 == 0) {System.out.println(Thread.currentThread().getName() + ":" + i);}}}
    }public class ThreadTest {public static void main(String[] args) {// 1.創(chuàng)建Thread類的子類的對象MyThread t1 = new MyThread();// 2.通過此對象調(diào)用start()t1.start();}
    }
    
  4. 多線程的創(chuàng)建二:實現(xiàn)Runnable接口

    • 創(chuàng)建一個實現(xiàn)了Runnable接口的類。
    • 實現(xiàn)類去實現(xiàn)Runnable中的抽象方法:run()
    • 創(chuàng)建實現(xiàn)類的對象。
    • 將此對象作為參數(shù)傳遞到Thread類的構(gòu)造器中,創(chuàng)建Thread類的對象。
    • 通過Thread類的對象調(diào)用start()。
    // 1.創(chuàng)建一個實現(xiàn)了Runnable接口的類
    class MThread implements Runnable {// 2.實現(xiàn)類去實現(xiàn)`Runnable`中的抽象方法:run()public void run() {for(int i = 0; i < 100; i++) {if(i % 2 == 0) {System.out.println(Thread.currentThread().getName() + ":" + i);}}}
    }public class ThreadTest1 {public static void main(String[] args) {// 3.創(chuàng)建實現(xiàn)類的對象MThread mThread = new MThread();// 4.將此對象作為參數(shù)傳遞到Thread類的構(gòu)造器中,創(chuàng)建Thread類的對象Thread t1 = new Thread(mThread);// 5.通過Thread類的對象調(diào)用start()t1.start();}
    }
    
  5. 比較創(chuàng)建線程的兩種方式

    • 開發(fā)中:優(yōu)先選擇實現(xiàn)Runnable接口的方式。
    • 原因:
      1. 實現(xiàn)的方式?jīng)]有類的單繼承性的局限性。
      2. 實現(xiàn)的方式更適合來處理多個線程有共享數(shù)據(jù)的情況。
    • 聯(lián)系:public class Thread implememts Runnable
    • 相同點:兩種方式都需要重寫run(),將線程要執(zhí)行的邏輯聲明在run()中。
  6. Thread中的常用方法

    • start():啟動當(dāng)前線程,調(diào)用當(dāng)前線程的run()
    • run():通常需要重寫Thread類中的此方法,將創(chuàng)建的線程要執(zhí)行的操作聲明在此方法中。
    • currentThread():靜態(tài)方法,返回執(zhí)行當(dāng)前代碼的線程。
    • getName():獲取當(dāng)前線程的名字。
    • setName():設(shè)置當(dāng)前線程的名字。
    • yield():釋放當(dāng)前cpu執(zhí)行權(quán)。
    • join():在線程a中調(diào)用線程bjoin(),此時線程a就進入阻塞狀態(tài),知道線程b完全執(zhí)行完以后,線程a才結(jié)束阻塞狀態(tài)。
    • stop():已過時。當(dāng)執(zhí)行此方法時,強制結(jié)束當(dāng)前線程。
    • isAlive():判斷當(dāng)前線程是否存活。
  7. 線程的優(yōu)先級

    MAX_PRIORITY: 10
    MIN_PRIORITY: 1
    NORM_PRIORITY: 5 --> 默認優(yōu)先級
    
    • 如何獲取和設(shè)置當(dāng)前線程的優(yōu)先級

      1. getPriority():獲取線程的優(yōu)先級。
      2. setPriority(int p):設(shè)置線程的優(yōu)先級。
    • 說明

      ? 高優(yōu)先級的線程要搶占低優(yōu)先級線程cpu的執(zhí)行權(quán)。但是只是從概率上講,高優(yōu)先級的線程高概率的情況下被執(zhí)行。并不意味著只有當(dāng)高優(yōu)先級的線程執(zhí)行完以后,低優(yōu)先級的線程才執(zhí)行。

  8. 線程的分類

    Java中的線程分為兩類:一種是守護線程,一種是用戶線程。

    • 它們在幾乎每個方面都是相同的,唯一的區(qū)別是判斷JVM何時離開。
    • 守護是用來服務(wù)用戶線程的,通過在start()方法前調(diào)用thread.setDaemon(true)可以把一個用戶線程變成一個守護線程。
    • Java垃圾回收就是一個典型的守護線程。
    • JVM中都是守護線程,當(dāng)前JVM將退出。

6.3:線程的生命周期

  1. JDK中用Thread.State類定義了線程的幾種狀態(tài)

    ? 想要實現(xiàn)多線程,必須在主線程中創(chuàng)建新的線程對象。Java語言使用Thread類及其子類的對象來表示線程,在它的一個完整的生命周期中通常要經(jīng)歷如下的五種狀態(tài)。

    • 新建

      當(dāng)一個Thread或其子類的對象被聲明并創(chuàng)建時,新生的線程對象處于新建狀態(tài)。

    • 就緒

      ? 處于新建狀態(tài)的線程被start()后,將進入線程隊列等待CPU時間片,此時它已具備了運行的條件,只是沒分配到CPU資源。

    • 運行

      當(dāng)就緒的線程被調(diào)度并獲得CPU資源時,便進入運行狀態(tài),run()方法定義了線程的操作和功能。

    • 阻塞

      在某種特殊情況下,被人為掛起或執(zhí)行輸入輸出操作時,讓出CPU并臨時中止自己的執(zhí)行,進入阻塞狀態(tài)。

    • 死亡

      線程完成了它的全部工作或線程被提前強制性地中止或出現(xiàn)異常導(dǎo)致結(jié)束。

  2. 線程的生命周期圖解
    在這里插入圖片描述

6.4:線程的同步

  1. 多線程出現(xiàn)了安全問題

    • 問題的原因

      ? 當(dāng)多條語句在操作同一個線程共享數(shù)據(jù)時,一個線程對多條語句只執(zhí)行了一部分,還沒有執(zhí)行完,另一個線程參與進來執(zhí)行,導(dǎo)致共享數(shù)據(jù)的錯誤。

    • 解決辦法

      ? 對多條操作共享數(shù)據(jù)的語句,只能讓一個線程都執(zhí)行完,在執(zhí)行過程中,其他線程不可以參與執(zhí)行。Java對于多線程的安全問題提供了專業(yè)的解決方式:同步機制。

  2. 方式一:同步代碼塊

    • 格式

      synchronized(同步監(jiān)視器) {// 需要被同步的代碼
      }
      
    • 操作共享數(shù)據(jù)的代碼,即為需要被同步的代碼。

    • 共享數(shù)據(jù):多個線程共同操作的變量。

    • 同步監(jiān)視器【俗稱:鎖】。任何一個類的對象,都可以充當(dāng)鎖。多個線程必須要共用同一把鎖。

    • 解決實現(xiàn)Runnable接口方式的線程安全問題

      class Window1 implements Runnable {private int ticket = 100;public void run() {while(true) {synchronized (this) {if (ticket > 0) {try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(getName() + ":買票,票號為:" + ticket);ticket--;} else {break;}}}}
      }public class WindowTest1 {public static void main(String[] args) {Window1 w = new Window1();Thread t1 = new Thread(w);Thread t2 = new Thread(w);Thread t3 = new Thread(w);t1.setName("窗口一");t2.setName("窗口二");t3.setName("窗口三");t1.start();t2.start();t3.start();}
      }
      

      在實現(xiàn)Runnable接口創(chuàng)建多線程的方式中,我們可以考慮使用this充當(dāng)同步監(jiān)視器。

    • 解決繼承Thread類方式的線程安全問題

      class Window2 extends Thread {private static int ticket = 100;public void run() {while(true) {synchronized(Window2.class) {if(ticket > 0) {try{Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(getName() + ":買票,票號為:" + ticket);ticket--;} else {break;}}}}
      }public class WindowTest2 {public static void main(String[] args) {Window2 t1 = new Window2();Window2 t2 = new Window2();Window2 t3 = new Window2();t1.setName("窗口一");t2.setName("窗口二");t3.setName("窗口三");t1.start();t2.start();t3.start();}
      }
      

      在繼承Thread類創(chuàng)建多線程的方式中,慎用this充當(dāng)同步監(jiān)視器,考慮使用當(dāng)前類充當(dāng)同步監(jiān)視器。

  3. 方式二:同步方法

    • 格式

      權(quán)限修飾符 synchronized 返回值類型 方法名() {}
      

      如果操作共享數(shù)據(jù)的代碼完整的聲明在以方法中,我們不妨將此方法聲明為同步的。

    • 同步方法仍然設(shè)計到同步監(jiān)視,只是不需要我們顯式的聲明。

    • 非靜態(tài)的同步方法,同步監(jiān)視器是this。靜態(tài)的同步方式,同步監(jiān)視器是當(dāng)前類本身。

    • 解決實現(xiàn)Runnable接口方式的線程安全問題

      class Window3 implements Runnable {private int ticket = 100;public void run() {while(true) {show();}}private synchronized void show() {if (ticket > 0) {try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(getName() + ":買票,票號為:" + ticket);ticket--;}}
      }public class WindowTest3 {public static void main(String[] args) {Window3 w = new Window3();Thread t1 = new Thread(w);Thread t2 = new Thread(w);Thread t3 = new Thread(w);t1.setName("窗口1");t2.setName("窗口2");t3.setName("窗口3");t1.start();t2.start();t3.start();}
      }
      
    • 解決繼承Thread類方式的線程安全問題

      class Window4 extends Thread {private static int ticket = 100;public void run() {while(true) {show();}}public static synchronized void show() {if(ticket > 0) {try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + ":買票,票號為:" + ticket);ticket--;}}
      }public class WindowTest4 {public static void main(String[] args) {Window4 t1 = new Window4();Window4 t2 = new Window4();Window4 t3 = new Window4();t1.setName("窗口1");t2.setName("窗口2");t3.setName("窗口3");t1.start();t2.start();t3.start();}
      }
      
  4. 方式三Lock(鎖)

    • JDK 5.0開始,Java提供了更強大的線程同步機制——通過顯示定義同步鎖對象來實現(xiàn)同步。同步鎖使用Lock對象充當(dāng)。
    • java.util.concurrent.locks.Lock接口是控制多個線程對共享資源進行訪問的工具。鎖提供了對共享資源的獨占訪問,每次只能有一個線程對Lock對象加鎖,線程開始訪問共享資源之前應(yīng)先獲得Lock對象。
    • ReentrantLock類實現(xiàn)了Lock,它擁有synchronized相同的并發(fā)性和內(nèi)存語義,在實現(xiàn)線程安全的控制中,比較常用的是ReentrantLock,可以顯示加鎖、釋放鎖。
    class Window implements Runnable {private int ticket = 100;// 1.實例化ReentrantLockprivate ReentrantLock lock = new ReentrantLock();public void run() {while(true) {try {// 2.調(diào)用鎖定方法lock()lock.lock();if(ticket > 0) {try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(getName() + ":售票,票號為:" + ticket);ticket--;} else {break;}} finally {// 3.調(diào)用解鎖方法:unlock()lock.unlock();}}}
    }public class LockTest {public static void main(String[] args) {Window w = new Window();Thread t1 = new Thread(w);Thread t2 = new Thread(w);Thread t3 = new Thread(w);t1.setName("窗口一");t2.setName("窗口二");t3.setName("窗口三");t1.start();t2.start();t3.start();}
    }
    
  5. synchronizedLock的異同

    相同點:二者都可以解決線程安全問題。

    不同點:

    • synchronized機制在執(zhí)行完相應(yīng)的同步代碼以后,自動的釋放同步監(jiān)視器。
    • Lock需要手動的啟動同步lock(),同時結(jié)束也需要手動的實現(xiàn)unlock()。
  6. 線程死鎖

    不同的線程分別占用對方需要的同步資源不放棄,都在等待對方放棄自己需要的同步資源,就形成了線程的死鎖。

    public class ThreadTest {public static void main(String[] args) {StringBuffer s1 = new StringBuffer();StringBuffer s2 = new StringBuffer();new Thread() {public void run() {synchronized(s1) {s1.append("a");s2.append("1");try{Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}synchronized (s2) {s1.append("b");s2.append("2");System.out.println(s1);System.out.println(s2);}}}}.start();new Thread(new Runnable() {public void run() {synchronized (s2) {s1.append("c");s2.append("3");try{Thread.sleep(100);}catch (InterruptedException e) {e.printStackTrace();}synchronized (s1) {s1.append("d");s2.append("4");System.out.println(s1);System.out.println(s2);}}}}).start();}
    }
    

    出現(xiàn)死鎖后,不會出現(xiàn)異常,不會出現(xiàn)提示,只是所有的線程都處于阻塞狀態(tài),無法繼續(xù)。

    • 解決方法:
      1. 專門的算法、原則。
      2. 盡量減少同步資源的定義。
      3. 盡量避免嵌套同步。

6.5:線程的通信

  1. 使用兩個線程交替打印1-100

    class Number implements Runnable {private int number = 1;public void run() {while(true) {synchronized (this) {// 線程通信方法二notify();if(number <= 100) {System.out.println(Thread.currentThread().getName() + ":" + number);number++;try{// 線程通信方法一wait();} catch (InterruptedException e) {e.printStackTrace();}} else {break;}}}}
    }public class CommunicationTest {public static void main(String[] args){Number number = new Number();Thread t1 = new Thread(number);Thread t2 = new Thread(number);t1.setName("線程1");t2.setName("線程2");t1.start();t2.start();}
    }
    
  2. 線程通信涉及到的方法

    • wait():一旦執(zhí)行此方法,當(dāng)前線程就進入阻塞狀態(tài),并釋放同步監(jiān)視器。
    • notify():一旦執(zhí)行此方法,就會喚醒被wait的一個線程。如果有多個線程被wait,就喚醒優(yōu)先級高的那個。
    • notifyAll():一旦執(zhí)行此方法,就會喚醒所有被wait的線程。
  3. 說明

    • wait()、notify()、notifyAll()這三個方法必須使用在同步代碼塊或同步方法中。
    • wait()、notify()、notifyAll()這三個方法的調(diào)用這必須是同步代碼塊或同步方法中的同步監(jiān)視器。否則會出現(xiàn)IllegalMonitorStateException異常。
    • wait()notify()、notifyAll()這三個方法是定義在java.lang.Object類中。
  4. sleep()wait()的異同

    • 相同點

      一旦執(zhí)行方法,都可以使得線程進入阻塞狀態(tài)。

    • 不同點

      1. 兩個方法聲明的位置不同:Thread類中聲明sleep()Object類中聲明wait()
      2. 調(diào)用的要求不同:sleep()可以在任何場景下調(diào)用。wait()必須使用在同步代碼塊或同步方法中。
      3. 關(guān)于釋放同步監(jiān)視器:如果兩個方法都使用在同步代碼塊或同步方法中,sleep()不會釋放鎖,wait()會釋放鎖。

6.6:JDK5.0新增線程創(chuàng)建方式

  1. 方式一:實現(xiàn)Callable接口

    • 與使用Runnable相比,Callable功能更強大一些。
      1. 相比run()方法,可以有返回值。
      2. 方法可以拋出異常。
      3. 支持泛型的返回值。
    • FutrueTask
      1. FutrueTaskFutrue接口的唯一實現(xiàn)類。
      2. FutrueTask同時實現(xiàn)了RunnableFuture接口。它既可以作為Runnable被線程執(zhí)行,又可以作為Future得到Callable的返回值。
    //1.創(chuàng)建一個實現(xiàn)Callable的實現(xiàn)類
    class NumThread implements Callable{//2.實現(xiàn)call方法,將此線程需要執(zhí)行的操作聲明在call()中@Overridepublic Object call() throws Exception {int sum = 0;for (int i = 1; i <= 100; i++) {if(i % 2 == 0){System.out.println(i);sum += i;}}return sum;}
    }public class ThreadNew {public static void main(String[] args) {//3.創(chuàng)建Callable接口實現(xiàn)類的對象NumThread numThread = new NumThread();//4.將此Callable接口實現(xiàn)類的對象作為傳遞到FutureTask構(gòu)造器中,創(chuàng)建FutureTask的對象FutureTask futureTask = new FutureTask(numThread);//5.將FutureTask的對象作為參數(shù)傳遞到Thread類的構(gòu)造器中,創(chuàng)建Thread對象,并調(diào)用start()new Thread(futureTask).start();try {//6.獲取Callable中call方法的返回值//get()返回值即為FutureTask構(gòu)造器參數(shù)Callable實現(xiàn)類重寫的call()的返回值。Object sum = futureTask.get();System.out.println("總和為:" + sum);} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}}
    }
    
  2. 方式二:使用線程池

    • 背景

      經(jīng)常創(chuàng)建和銷毀、使用量特別大的資源【并發(fā)情況下的線程】,對性能影響很大。

    • 思路

      提前創(chuàng)建好多個線程,放入線程池中,使用時直接獲取,用完放回池中。可以避免頻繁創(chuàng)建銷毀、實現(xiàn)重復(fù)利用

    • 好處

      1. 提高響應(yīng)速度【減少了創(chuàng)建新線程的時間】。
      2. 降低資源消耗【重復(fù)利用線程池中線程,不需要每次都創(chuàng)建】。
      3. 便于線程管理。
    • 線程池相關(guān)API

      1. JDK 5.0起提供了線程池相關(guān)APIExecutoServiceExecutors。
      2. ExecutorService:真正的線程池接口。常見子類ThreadPoolExecutor
        • void execute(Runnable command):執(zhí)行任務(wù)/命令,沒有返回值,一般用來執(zhí)行Runnable
        • <T> Future<T> submit(Callable<T> task):執(zhí)行任務(wù),有返回值,一般又來執(zhí)行Callable
        • void shutdown():關(guān)閉連接池
      3. Executors:工具類、線程池的工廠類,用于創(chuàng)建并返回不同類型的線程池。
        • Executors.newCachedThreadPool():創(chuàng)建一個可根據(jù)需要創(chuàng)建新線程的線程池
        • Executors.newFixedThreadPool(n):創(chuàng)建一個可重用固定線程數(shù)的線程池
        • Executors.newSingleThreadExecutor():創(chuàng)建一個只有一個線程的線程池
        • Executors.newScheduledThreadPool(n):創(chuàng)建一個線程池,它可安排在給定延遲后運行命令或定期執(zhí)行
    class NumberThread implements Runnable{@Overridepublic void run() {for(int i = 0;i <= 100;i++){if(i % 2 == 0){System.out.println(Thread.currentThread().getName() + ": " + i);}}}
    }public class ThreadPool {public static void main(String[] args) {//1. 提供指定線程數(shù)量的線程池ExecutorService service = Executors.newFixedThreadPool(10);//2.執(zhí)行指定的線程的操作。需要提供實現(xiàn)Runnable接口或Callable接口實現(xiàn)類的對象service.execute(new NumberThread());//3.關(guān)閉連接池service.shutdown();}
    }
    
http://www.risenshineclean.com/news/37341.html

相關(guān)文章:

  • 漂亮企業(yè)網(wǎng)站源碼關(guān)鍵詞優(yōu)化排名軟件
  • 網(wǎng)站設(shè)計概述500字關(guān)鍵詞批量調(diào)詞軟件
  • 學(xué)生做爰網(wǎng)站微信群推廣網(wǎng)站
  • 專業(yè)鄭州做網(wǎng)站的公司今日國家新聞
  • 動態(tài)網(wǎng)站開發(fā)結(jié)束語東莞優(yōu)化怎么做seo
  • 彩票網(wǎng)站建設(shè)方案看網(wǎng)站時的關(guān)鍵詞
  • 百度競價 十一 pc網(wǎng)站 手機網(wǎng)站seo技術(shù)團隊
  • 岳陽市委網(wǎng)站免費seo網(wǎng)站推廣在線觀看
  • 湛江網(wǎng)站設(shè)計模板視頻500個游戲推廣群
  • 網(wǎng)站互動營銷成人編程培訓(xùn)機構(gòu)排名前十
  • 融資是什么意思株洲seo優(yōu)化報價
  • 馬云1688網(wǎng)站在濮陽如何做圖片外鏈在線生成
  • 大型b2c網(wǎng)站開發(fā)百度推廣app下載官方
  • 怎么做領(lǐng)券網(wǎng)站上海知名seo公司
  • 電腦做網(wǎng)站電腦編程百度指數(shù)怎么提升
  • 手機視頻網(wǎng)站怎么做保定seo推廣公司
  • 尚云網(wǎng)站建設(shè)廣東網(wǎng)約車漲價
  • 可以做書的網(wǎng)站湘潭seo優(yōu)化
  • 網(wǎng)站建設(shè) 加強宣傳百度開戶資質(zhì)
  • 昆明網(wǎng)站建設(shè)_云南網(wǎng)站建設(shè)網(wǎng)頁設(shè)計制作
  • 服務(wù)器做兩個網(wǎng)站電視劇排行榜百度搜索風(fēng)云榜
  • 做網(wǎng)站需要哪些知識論述搜索引擎優(yōu)化的具體措施
  • asp網(wǎng)站建設(shè)實驗設(shè)計推廣軟文是什么意思
  • 論述制作網(wǎng)站的一般過程百度移動端關(guān)鍵詞優(yōu)化
  • title wordpress企業(yè)站seo價格
  • 網(wǎng)站建設(shè)包含哪些內(nèi)容巨量算數(shù)數(shù)據(jù)分析入口
  • 服務(wù)器網(wǎng)站部署嘉興網(wǎng)絡(luò)推廣
  • 好創(chuàng)意的設(shè)計網(wǎng)站最大免費廣告發(fā)布平臺
  • 找人做網(wǎng)站排名優(yōu)化山西seo排名廠家
  • 網(wǎng)站開發(fā)的著作權(quán)和版權(quán)進一步優(yōu)化落實