最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

新手初學(xué)Java網(wǎng)絡(luò)編程

 更新時(shí)間:2021年07月07日 14:38:19   作者:頂風(fēng)少年  
網(wǎng)絡(luò)編程是指編寫運(yùn)行在多個(gè)設(shè)備(計(jì)算機(jī))的程序,這些設(shè)備都通過(guò)網(wǎng)絡(luò)連接起來(lái)。本文介紹了一些網(wǎng)絡(luò)編程基礎(chǔ)的概念,并用Java來(lái)實(shí)現(xiàn)TCP和UDP的Socket的編程,來(lái)讓讀者更好的了解其原理

運(yùn)行線程

創(chuàng)建Thread的子類

public class ThreadChild extends Thread {
    @Override
    public void run() {
        while (true) {
            System.out.println("run");
        }
    }
}
public class Test {
    public static void main(String[] args) throws Exception {
        ThreadChild t = new ThreadChild();
        t.start();
    }
}

創(chuàng)建Thread傳入Runnable接口實(shí)現(xiàn)類

public class RunnableImpl implements Runnable {
    @Override
    public void run() {
        while (true) {
            System.out.println("run");
        }
    }
}
public class Test {
    public static void main(String[] args) throws Exception {
        Thread t = new Thread(new RunnableImpl());
        t.start();
    }
}

回調(diào)

ExecutorService線程池的Submit()可接收Runnable或者Callable.Callable執(zhí)行結(jié)束后有返回值,Runnable執(zhí)行結(jié)束后沒(méi)有返回值.可以通過(guò)submit的返回對(duì)象Future的get方法獲取返回返回值,需要注意的是get方法是一個(gè)阻塞方法.若線程沒(méi)有執(zhí)行完畢,則會(huì)阻塞get()直到線程執(zhí)行結(jié)束后返回?cái)?shù)據(jù).

public static void main(String[] args) throws Exception {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        Future<Integer> future = executorService.submit(() -> {
            TimeUnit.SECONDS.sleep( 3);
            return 1;
        });
        Future<?> future2 = executorService.submit(() -> {
        });
        Future<String> future3 = executorService.submit(() -> {
        }, "aaa");
        System.out.println(future.get());
        System.out.println(future2.get());
        System.out.println(future3.get());
    }

同步方法

synchronized關(guān)鍵字和方法組合使用后,該方法是一個(gè)同步方法。同步方法都有一個(gè)隱試的鎖,多個(gè)線程同時(shí)執(zhí)行該方法時(shí),只能順序執(zhí)行,未強(qiáng)到鎖的線程處于阻塞狀態(tài)。另外靜態(tài)方法和非靜態(tài)方法使用的是不同的鎖,非靜態(tài)方法的鎖是對(duì)象鎖,若兩個(gè)線程通過(guò)兩個(gè)該類的對(duì)象調(diào)用那么互不影響。靜態(tài)方法是類鎖,即本類的Class對(duì)象。同步方法無(wú)法指定鎖資源,要么是this鎖,要么是Class鎖。

public class Test {
    public static void main(String[] args) throws Exception {
        Test test = new Test();
        Thread t1 = new Thread(()->{
            test.synFunction();
        });
        Thread t2 = new Thread(()->{
            test.synFunction();
        });
        t1.start();
        t2.start();
    }
    public synchronized void synFunction(){
        try {
            System.out.println("-------------");
            TimeUnit.SECONDS.sleep(3);
        }catch (Exception e) {}        
    }
}
public class Test {
    public static void main(String[] args) throws Exception {
        Thread t1 = new Thread(()->{
            Test.synFunction();
        });
        Thread t2 = new Thread(()->{
            Test.synFunction();
        });
        t1.start();
        t2.start();
    }
    public static synchronized void synFunction(){
        try {
            System.out.println("-------------");
            TimeUnit.SECONDS.sleep(3);
        }catch (Exception e) {}        
    }
}

同步塊

同步代碼塊可以指定鎖對(duì)象,非靜態(tài)方法可以指定任意的對(duì)象鎖,或者任意的類鎖。但靜態(tài)方法只能使用任意的類鎖。

public class Test {
    public static void main(String[] args) throws Exception {
        Test lock = new Test();
        Thread t1 = new Thread(() -> {
            lock.synFunction();
        });
        Thread t2 = new Thread(() -> {
            lock.synFunction();
        });
        t1.start();
        t2.start();
    }
    public void synFunction() {
        synchronized (this) {//對(duì)象鎖
            try {
                System.out.println("-------------");
                TimeUnit.SECONDS.sleep(3);
            } catch (Exception e) {
            }
        }
    }
}
public class Test {
    public static void main(String[] args) throws Exception {
        Test lock1 = new Test();
        Test lock2 = new Test();
        Thread t1 = new Thread(() -> {
            lock1.synFunction(lock1);
        });
        Thread t2 = new Thread(() -> {
            lock2.synFunction(lock2);
        });
        t1.start();
        t2.start();
    }
    public void synFunction(Object lock) {
        synchronized (lock) {//對(duì)象鎖
            try {
                System.out.println("-------------");
                TimeUnit.SECONDS.sleep(3);
            } catch (Exception e) {
            }
        }
    }
}
public class Test {
    public static void main(String[] args) throws Exception {
        Test lock1 = new Test();
        Test lock2 = new Test();
        Thread t1 = new Thread(() -> {
            lock1.synFunction();
        });
        Thread t2 = new Thread(() -> {
            lock2.synFunction();
        });
        t1.start();
        t2.start();
    }
    public void synFunction() {
        synchronized (Test.class) {//類鎖
            try {
                System.out.println("-------------");
                TimeUnit.SECONDS.sleep(3);
            } catch (Exception e) {
            }
        }
    }
}
public class Test {
    public static void main(String[] args) throws Exception {
        Thread t1 = new Thread(() -> {
            Test.synFunction();
        });
        Thread t2 = new Thread(() -> {
            Test.synFunction();
        });
        t1.start();
        t2.start();
    }
    public static void synFunction() {
        synchronized (Object.class) {//類鎖
            try {
                System.out.println("-------------");
                TimeUnit.SECONDS.sleep(3);
            } catch (Exception e) {
            }
        }
    }
}

死鎖

當(dāng)多個(gè)線程競(jìng)爭(zhēng)鎖時(shí),可能會(huì)導(dǎo)致死鎖。一個(gè)線程由于沒(méi)有得到一個(gè)鎖而阻塞它也不會(huì)釋放已經(jīng)獲取的鎖。方法1獲取鎖的順序是Test.class,Object.class。方法2獲取鎖的順序是Object.class,Test.class。程序會(huì)陷入死鎖。

public class Test {
    public static void main(String[] args) throws Exception {
        Thread t1 = new Thread(() -> {
            Test.synFunction1();
        });
        Thread t2 = new Thread(() -> {
             Test.synFunction2();
        });
        t1.start();
        t2.start();
    }
    public static void synFunction1() {
        synchronized (Test.class) {// 類鎖
            try {
                System.out.println("synFunction1-------------AAAAAAAAAAAAA");
                synchronized (Object.class) {// 類鎖
                    try {
                        System.out.println("synFunction1-------------bbbbbbbbbbbbb");
                    } catch (Exception e) {
                    }
                }
            } catch (Exception e) {
            }
        }    
    }
    public static void synFunction2() {
        synchronized (Object.class) {// 類鎖
            try {
                System.out.println("synFunction2-------------AAAAAAAAAAAAA");
            } catch (Exception e) {
            }
            synchronized (Test.class) {// 類鎖
                try {
                    System.out.println("synFunction2-------------bbbbbbbbbbbbb");
                } catch (Exception e) {
                }
            }
        }
    }
}

優(yōu)先級(jí)

不是所有線程創(chuàng)建時(shí)都是均等的,每個(gè)線程都有一個(gè)優(yōu)先級(jí),指定從0-10的整數(shù)。當(dāng)多個(gè)線程運(yùn)行時(shí),虛擬機(jī)通常只運(yùn)行最高優(yōu)先級(jí)的線程,但這并不是一個(gè)嚴(yán)格的規(guī)則。在Java中10是最高優(yōu)先級(jí),0是最低優(yōu)先級(jí)。默認(rèn)優(yōu)先級(jí)為5.并不是所有操作系統(tǒng)都支持這11個(gè)優(yōu)先級(jí)。例如Windows只有7個(gè)優(yōu)先級(jí)。優(yōu)先級(jí)(1,2)(3,4)(6,7)(8,9)會(huì)做同樣的處理。

public class Test {
    public static void main(String[] args) throws Exception {
        Thread t1 = new Thread(() -> {
            Test.synFunction("aaaaaaaaaaa");
        });
        Thread t2 = new Thread(() -> {
             Test.synFunction("bbbbbbbbbb");
        });
        t2.setPriority(9);
        t1.setPriority(1);
        t1.start();
        t2.start();
    }
    public static void synFunction(String name) {
        System.out.println(name+"--------------");
    }
}

暫停

為了能讓其他線程有機(jī)會(huì)運(yùn)行,一個(gè)線程有8中方式可以暫?;蛘咧甘舅鼫?zhǔn)備暫停。

可以對(duì)IO阻塞

要讓網(wǎng)絡(luò)程序中的線程自動(dòng)放棄CPU控制權(quán),最常見(jiàn)的方式是IO阻塞。由于CPU比網(wǎng)絡(luò)和磁盤快的多,網(wǎng)絡(luò)程序經(jīng)常會(huì)在等待數(shù)據(jù)從網(wǎng)絡(luò)到達(dá)或向網(wǎng)絡(luò)發(fā)送數(shù)據(jù)時(shí)阻塞。即使只阻塞幾毫秒,這一點(diǎn)時(shí)間也足夠其他線程用來(lái)完成重要的任務(wù)。

可以對(duì)同步對(duì)象阻塞

線程在進(jìn)入一個(gè)同步方法或代碼塊時(shí)也會(huì)阻塞。如果這個(gè)線程沒(méi)有所同步對(duì)象的鎖,而其他線程擁有這個(gè)鎖,這個(gè)線程就會(huì)暫停,直到鎖被釋放為止。如果這個(gè)鎖永遠(yuǎn)不會(huì)釋放,那么這個(gè)線程會(huì)永久停止。

可以放棄

調(diào)用Thread.yield()靜態(tài)方法可以做到顯試的放棄線程控制權(quán),這將通知虛擬機(jī),可以優(yōu)先執(zhí)行其他線程。放棄并不會(huì)釋放這個(gè)線程擁有的鎖,因此在理想情況下被放棄的線程不要做任何的同步。如果等待運(yùn)行的其他線程都是因?yàn)檫@個(gè)線程所擁有的同步資源而阻塞,那么這些線程將不能運(yùn)行。實(shí)際上,控制權(quán)將回到唯一可以運(yùn)行的線程,即剛剛放棄的這個(gè)線程,這很大程度上失去了放棄的意義。

public class Test {
    public static void main(String[] args) throws Exception {
        Thread t1 = new Thread(() -> {
            Test.synFunction("aaaaaaaaaaa");
        });
        Thread t2 = new Thread(() -> {
            Test.synFunction2("bbbbbbbbbb");
        });
        t1.start();
        t2.start();
    }
    public static void synFunction(String name) {
        for (int i = 0;; i++) {
            Thread.yield();
            System.out.println(name + "--------------" + i);
        }
    }
    public static void synFunction2(String name) {
        for (int i = 0;; i++)
            System.out.println(name + "--------------"+i);
    }
}

可以休眠

休眠是更有利的放棄方式。放棄只是表示線程愿意暫停,讓其他有相同優(yōu)先級(jí)的線程有機(jī)會(huì)運(yùn)行,而進(jìn)入休眠的線程有所不同,不管有沒(méi)有其他線程準(zhǔn)備運(yùn)行,休眠線程都會(huì)暫停。這樣一來(lái),不只是其他有相同優(yōu)先級(jí)的線程會(huì)得到機(jī)會(huì),還會(huì)給較低優(yōu)先級(jí)的線程運(yùn)行機(jī)會(huì)。不過(guò)進(jìn)入休眠的線程仍然擁有它已經(jīng)獲得得所有鎖。因此其他需要相同鎖得線程依然會(huì)阻塞,要避免在同步方法或塊內(nèi)讓線程休眠。

public class Test {
    public static void main(String[] args) throws Exception {
        Thread t1 = new Thread(() -> {
            Test.synFunction("aaaaaaaaaaa");
        });
        Thread t2 = new Thread(() -> {
            Test.synFunction2("bbbbbbbbbb");
        });
        t1.start();
        t2.start();
    }
    public synchronized static void synFunction(String name) {
        try {
            System.out.println(name);
            Thread.sleep(1000 * 10);
        } catch (Exception e) {
        }
    }
    public synchronized static void synFunction2(String name) {
        System.out.println(name);
    }
}
package com.datang.bingxiang.demo;
import java.util.concurrent.TimeUnit;
public class Test {
    public static void main(String[] args) throws Exception {
        Thread t1 = new Thread(() -> {
            Test.synFunction("aaaaaaaaaaa");
        });
        Thread t2 = new Thread(() -> {
            Test.synFunction2("bbbbbbbbbb");
        });
        t1.start();
        t2.start();
    }
    public synchronized static void synFunction(String name) {
        try {
            System.out.println(name);
            Thread.sleep(1000 * 3, 999999);//3000毫秒+999999毫秒(第二個(gè)參數(shù)不能超過(guò)999999,也就是不能超過(guò)1毫秒)
        } catch (Exception e) {
            System.out.println(e);
        }
    }
    public synchronized static void synFunction2(String name) {
        System.out.println(name);
    }
}

可以連接另一個(gè)線程

連接線程(既調(diào)用join()方法得線程A)等待被連接的線程(join()方法所屬的線程對(duì)象B)執(zhí)行完畢后才會(huì)執(zhí)行。在A線程調(diào)用B線程的join()A線程會(huì)等待B線程執(zhí)行結(jié)束后才會(huì)繼續(xù)執(zhí)行。要注意的是A線程并不會(huì)釋放已經(jīng)獲取的鎖資源。

public class Test {
    public static void main(String[] args) throws Exception {
        Thread t2 = new Thread(() -> {
            Test.synFunction2("bbbbbbbbbb");
        });
        Thread t1 = new Thread(() -> {
            Test.synFunction("aaaaaaaaaaa",t2);
        });
        
        t1.start();
        t2.start();
    }
    public  static void synFunction(String name,Thread t) {
        try {
            t.join();
            //t.join(1000);
            //t.join(1000,999999);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        for (int i = 0; i < 5; i++) {
            System.out.println(name);
        }
    }
    public  static void synFunction2(String name) {
        try {
            Thread.sleep(1000*3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        for (int i = 0; i < 5; i++) {
            System.out.println(name);
        }
    }
}

可以等待一個(gè)對(duì)象

線程可以等待一個(gè)它鎖定的對(duì)象.在等待時(shí),它會(huì)釋放這個(gè)對(duì)象的鎖并暫停,直到它得到其他線程的通知.另一個(gè)線程以某種方式修改這個(gè)對(duì)象,通知等待對(duì)象的線程,然后繼續(xù)執(zhí)行.等待會(huì)暫停執(zhí)行,直到一個(gè)對(duì)象或資源到達(dá)某種狀態(tài).實(shí)際上,要等待某個(gè)特定的對(duì)象,希望暫停的線程首先必須使用synchronized獲得這個(gè)對(duì)象的鎖,然后調(diào)用這個(gè)對(duì)象的三個(gè)重載wait()方法之一.

public class Demo {
    public static void main(String[] args) throws Exception {
        Demo d = new Demo();
        Thread t1 = new Thread(() -> {
            d.a();
        });
        Thread t2 = new Thread(() -> {
            d.b();
        });
        t1.start();
        t2.start();
    }
    boolean flag = true;
    public synchronized void a() {
        try {
            while (true) {
                if (flag) {
                    System.out.println("執(zhí)行AAAAAAAAAAA");
                    flag = false;
                } else {
                    wait();//等待,不限制等待時(shí)間
                    //wait(1000);//等待指定的時(shí)間,沒(méi)有被notify喚醒也可以自己退出等待
                    //wait(1000,999999);//毫秒+納秒的等待時(shí)間
                }
                notify();
            }
        } catch (Exception e) {
        }
    }
    public synchronized void b() {
        try {
            while (true) {
                if (!flag) {
                    System.out.println("執(zhí)行BBBBBBBBBBB");
                    flag = true;
                } else {
                    wait();
                }
                notify();
            }
        } catch (Exception e) {
        }
    }
}

可以結(jié)束

線程要以合理的方式放棄CPU控制權(quán),一種方式是結(jié)束.當(dāng)run()方法返回線程時(shí),線程將撤銷,其他線程可以接管CPU.在網(wǎng)絡(luò)應(yīng)用程序中,包裝一個(gè)阻塞操作的線程往往會(huì)這么做,例如線程從服務(wù)器下載一個(gè)文件,這樣應(yīng)用程序的其他部分就不會(huì)被阻塞.另一方面,如果run()方法太簡(jiǎn)單,總是很快結(jié)束,而不會(huì)紫色,那就存在一個(gè)很實(shí)際的問(wèn)題:到底有沒(méi)有必要生成一個(gè)線程.虛擬機(jī)在建立和撤銷線程時(shí)會(huì)有很大的開銷.如果線程會(huì)在極端的時(shí)間內(nèi)結(jié)束,那么使用一次簡(jiǎn)單的方法調(diào)用而不是單獨(dú)的線程可能會(huì)結(jié)束的更快.

可以被更高優(yōu)先級(jí)線程搶占

Thread的setPriority(int priority)設(shè)置線程的優(yōu)先級(jí).

總結(jié)

本篇文章就到這里了,希望能給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • Springboot 實(shí)現(xiàn)數(shù)據(jù)庫(kù)備份還原的方法

    Springboot 實(shí)現(xiàn)數(shù)據(jù)庫(kù)備份還原的方法

    這篇文章主要介紹了Springboot 實(shí)現(xiàn)數(shù)據(jù)庫(kù)備份還原的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-09-09
  • Java手寫簡(jiǎn)易版HashMap的使用(存儲(chǔ)+查找)

    Java手寫簡(jiǎn)易版HashMap的使用(存儲(chǔ)+查找)

    這篇文章主要介紹了Java手寫簡(jiǎn)易版HashMap的使用(存儲(chǔ)+查找),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-01-01
  • Java基于UDP協(xié)議的聊天室功能

    Java基于UDP協(xié)議的聊天室功能

    這篇文章主要為大家詳細(xì)介紹了Java基于UDP協(xié)議的聊天室功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-09-09
  • Spring Boot集成Druid數(shù)據(jù)庫(kù)連接池

    Spring Boot集成Druid數(shù)據(jù)庫(kù)連接池

    這篇文章主要介紹了Spring Boot集成Druid數(shù)據(jù)庫(kù)連接池,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-04-04
  • 詳解Java8合并兩個(gè)Map中元素的正確姿勢(shì)

    詳解Java8合并兩個(gè)Map中元素的正確姿勢(shì)

    這篇文章主要介紹了詳解Java8合并兩個(gè)Map中元素的正確姿勢(shì),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • string boot 與 自定義interceptor的實(shí)例講解

    string boot 與 自定義interceptor的實(shí)例講解

    下面小編就為大家分享一篇string boot 與 自定義interceptor的實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2017-12-12
  • JAVA調(diào)用Deepseek的api完成基本對(duì)話簡(jiǎn)單代碼示例

    JAVA調(diào)用Deepseek的api完成基本對(duì)話簡(jiǎn)單代碼示例

    這篇文章主要介紹了JAVA調(diào)用Deepseek的api完成基本對(duì)話的相關(guān)資料,文中詳細(xì)講解了如何獲取DeepSeek?API密鑰、添加HTTP客戶端依賴、創(chuàng)建HTTP請(qǐng)求并使用示例代碼來(lái)對(duì)接DeepSeek?API,需要的朋友可以參考下
    2025-02-02
  • Java中如何使用正則表達(dá)式提取各種類型括號(hào)中的內(nèi)容

    Java中如何使用正則表達(dá)式提取各種類型括號(hào)中的內(nèi)容

    最近在工作中遇到一個(gè)問(wèn)題,就是需要一個(gè)字符串中每一個(gè)中括號(hào)里的內(nèi)容,下面這篇文章主要給大家介紹了關(guān)于Java中如何使用正則表達(dá)式提取各種類型括號(hào)中的內(nèi)容,需要的朋友可以參考下
    2023-06-06
  • spring boot使用thymeleaf為模板的基本步驟介紹

    spring boot使用thymeleaf為模板的基本步驟介紹

    Spring Boot項(xiàng)目的默認(rèn)模板引擎是Thymeleaf,這沒(méi)什么好說(shuō)的,個(gè)人覺(jué)得也非常好,下面這篇文章主要給大家介紹了關(guān)于spring boot使用thymeleaf為模板的相關(guān)資料,需要的朋友可以參考借鑒,下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-01-01
  • Logback的使用及如何配置

    Logback的使用及如何配置

    這篇文章主要介紹了Logback的使用及如何配置,幫助大家更好的理解和學(xué)習(xí)使用Logback,感興趣的朋友可以了解下
    2021-03-03

最新評(píng)論

应用必备| 镇巴县| 赣州市| 化隆| 阳高县| 故城县| 平遥县| 分宜县| 连云港市| 宁晋县| 林芝县| 偃师市| 石嘴山市| 大冶市| 瓦房店市| 尉犁县| 石狮市| 黑水县| 隆尧县| 孝义市| 柳州市| 大兴区| 阿尔山市| 仙桃市| 汪清县| 临江市| 通河县| 沧源| 平谷区| 资阳市| 孟州市| 芮城县| 沿河| 上饶市| 抚远县| 满洲里市| 涞水县| 宁乡县| 上虞市| 随州市| 玉屏|