欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java學(xué)習(xí)之線程同步與線程間通信詳解

 更新時(shí)間:2022年12月27日 16:25:43   作者:從未止步..  
這篇文章主要為大家詳細(xì)介紹了線程同步和線程之間的通信的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Java有一定的幫助,感興趣的可以了解一下

線程同步的概念

由于同一個(gè)進(jìn)程的多個(gè)線程共享同一塊存儲(chǔ)空間,在帶來(lái)方便的同時(shí),也會(huì)帶來(lái)訪問(wèn)沖突的問(wèn)題:

舉例:

public class Runnable_test implements Runnable {//實(shí)現(xiàn)Runnable接口
private  int ticknumbers=10;

    @Override
    public void run() {
        while(true){
            if(ticknumbers<=0){
                break;
            }
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"-->拿到了第"+ticknumbers--+"票");//currentThread()監(jiān)測(cè)線程的狀態(tài)
        }
    }

    public static void main(String[] args) {
        Runnable_test runnable_test=new Runnable_test();
        new Thread(runnable_test,"小明").start();
        new Thread(runnable_test,"小黃").start();
        new Thread(runnable_test,"小紅").start();
    }
}

在輸出的數(shù)據(jù)中,顯然出現(xiàn)了,一張票同時(shí)被大于1人拿到的情況,這與我們的現(xiàn)實(shí)顯然不相符合。

為了解決此問(wèn)題,Java 語(yǔ)言提供專(zhuān)門(mén)的機(jī)制來(lái)避免同一個(gè)對(duì)象被多個(gè)線程同時(shí)訪問(wèn),這個(gè)機(jī)制就是線程同步。

當(dāng)兩個(gè)或多個(gè)線程同時(shí)訪問(wèn)同一個(gè)變量,并且有線程需要修改這個(gè)變量時(shí),就必須采用同步的機(jī)制對(duì)其進(jìn)行控制,否則就會(huì)出現(xiàn)邏輯錯(cuò)誤的運(yùn)行結(jié)果

造成上述這種錯(cuò)誤邏輯結(jié)果的原因是:可能有多個(gè)線程取得的是同一個(gè)值,各自修改并存入,從而造成修改慢的后執(zhí)行的線程把執(zhí)行快的線程的修改結(jié)果覆蓋掉了

因?yàn)榫€程在執(zhí)行過(guò)程中不同步,多個(gè)線程在訪問(wèn)同一資源時(shí),需要進(jìn)行同步操作,被訪問(wèn)的資源稱(chēng)為共享資源。

同步的本質(zhì)是加鎖,Java 中的任何一個(gè)對(duì)象都有一把鎖以及和這個(gè)鎖對(duì)應(yīng)的等待隊(duì)列,當(dāng)線程要訪問(wèn)共享資源時(shí),首先要對(duì)相關(guān)的對(duì)象進(jìn)行加鎖

如果加鎖成功,線程對(duì)象才能訪問(wèn)共享資源并且在訪問(wèn)結(jié)束后,要釋放鎖:如果加鎖不成功,那么線程進(jìn)入被加鎖對(duì)象對(duì)應(yīng)的是等待隊(duì)列。

Java用synchronized關(guān)鍵字給針對(duì)共享資源進(jìn)行操作的方法加鎖。每個(gè)鎖只有一把鑰匙,只有得到這把鑰匙之后才可以對(duì)被保護(hù)的資源進(jìn)行操作,而其他線程只能等待,直到拿到這把鑰匙。

實(shí)現(xiàn)同步的具體方式有同步代碼塊和同步方法兩種

同步代碼塊

使用 synchronized 關(guān)鍵字聲明的代碼塊稱(chēng)為同步代碼塊。

在任意時(shí)刻,只能有一個(gè)線程訪問(wèn)同步代碼塊中的代碼,所以同步代碼塊也稱(chēng)為互斥代碼塊

同步代碼塊格式如下所示:

synchronized(同步對(duì)象){
//需要同步的代碼,對(duì)共享資源的訪問(wèn)
}

synchronized關(guān)鍵字后面括號(hào)內(nèi)的對(duì)象就是被加載的對(duì)象,同步代碼塊要實(shí)現(xiàn)對(duì)共享資源的訪問(wèn)

對(duì)上述實(shí)例進(jìn)行修改:

package Runnable;

public class Runnable_test implements Runnable {//實(shí)現(xiàn)Runnable接口
    private int ticknumbers = 20;
    private Object obj = new Object();//被加鎖的對(duì)象,同步對(duì)象

    @Override
    public void run() {
        while (true) {
            synchronized (obj) {
                if (ticknumbers > 0) {
                    System.out.println(Thread.currentThread().getName() + "-->拿到了第" + ticknumbers-- + "票");//currentThread()監(jiān)測(cè)線程的狀態(tài)
                    try {
                        Thread.sleep(300);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } else
                    break;
            }
        }
    }
}


class test{
    public static void main(String[] args) {
        Runnable_test runnable_test=new Runnable_test();
        new Thread(runnable_test,"小明").start();
        new Thread(runnable_test,"小黃").start();
        new Thread(runnable_test,"小紅").start();
    }
}

將票數(shù)產(chǎn)生變化的代碼塊修改為同步代碼塊:

修改過(guò)后輸出,我們發(fā)現(xiàn),并未出現(xiàn)同一張票,被第二個(gè)甚至第三個(gè)人拿到的情況:

小明-->拿到了第20票
小明-->拿到了第19票
小明-->拿到了第18票
小明-->拿到了第17票
小明-->拿到了第16票
小明-->拿到了第15票
小紅-->拿到了第14票
小紅-->拿到了第13票
小紅-->拿到了第12票
小黃-->拿到了第11票
小黃-->拿到了第10票
小黃-->拿到了第9票
小黃-->拿到了第8票
小紅-->拿到了第7票
小紅-->拿到了第6票
小紅-->拿到了第5票
小紅-->拿到了第4票
小紅-->拿到了第3票
小紅-->拿到了第2票
小紅-->拿到了第1票

在上面的修改中,僅僅是將需要互斥的代碼放人了同步塊中。此時(shí),在抽票的過(guò)程中通過(guò)給同一個(gè) obj對(duì)象加鎖來(lái)實(shí)現(xiàn)互斥,從而保證線程的同步執(zhí)行。

同步方法

synchronized關(guān)鍵字也可以出現(xiàn)在方法的聲明部分,該方法稱(chēng)為同步方法

當(dāng)多個(gè)線程對(duì)象同時(shí)訪問(wèn)共享資源時(shí),只有獲得鎖對(duì)象的線程才能進(jìn)入同步方法執(zhí)行,其他訪問(wèn)共享資源的線程將會(huì)進(jìn)入鎖對(duì)象的等待隊(duì)列,執(zhí)行完同步方法的線程會(huì)釋放鎖。

[權(quán)限訪問(wèn)限定]    synchronized 方法返回值 方法名稱(chēng)(參數(shù)列表){
//.............需要同步的代碼,對(duì)共享資源的訪問(wèn)
}

package Runnable;

public class Runnable_test implements Runnable {//實(shí)現(xiàn)Runnable接口
    private int ticknumbers = 20;
    @Override
    public  void run() {
        while (true) {
            if (ticknumbers > 0) {
                ticks();//調(diào)用同步方法
            }
        else
            break;
        }
    }
    
    //同步方法
    public synchronized void ticks(){
        if (ticknumbers > 0) {
            System.out.println(Thread.currentThread().getName() + "-->拿到了第" + ticknumbers-- + "票");
            try {
                Thread.sleep(300);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

//測(cè)試類(lèi)
class test{
    public static void main(String[] args) {
        Runnable_test runnable_test=new Runnable_test();
        new Thread(runnable_test,"小明").start();
        new Thread(runnable_test,"小黃").start();
        new Thread(runnable_test,"小紅").start();
    }
}

輸出:

小明-->拿到了第20票
小明-->拿到了第19票
小明-->拿到了第18票
小明-->拿到了第17票
小明-->拿到了第16票
小黃-->拿到了第15票
小黃-->拿到了第14票
小黃-->拿到了第13票
小黃-->拿到了第12票
小黃-->拿到了第11票
小黃-->拿到了第10票
小黃-->拿到了第9票
小紅-->拿到了第8票
小紅-->拿到了第7票
小紅-->拿到了第6票
小紅-->拿到了第5票
小紅-->拿到了第4票
小紅-->拿到了第3票
小紅-->拿到了第2票
小紅-->拿到了第1票

同步方法的本質(zhì)也是給對(duì)象加鎖,但是是給同步方法所在類(lèi)的 this 對(duì)象加鎖,所以在上述實(shí)例中,我們就刪除了obj對(duì)象的定義。

package Runnable;

public class Runnable_test implements Runnable {//實(shí)現(xiàn)Runnable接口
    private int ticknumbers = 20;
    boolean tag = false;//設(shè)置此變量的作用是為了讓一個(gè)線程進(jìn)入同步塊,另一個(gè)線程進(jìn)入同步方法

    @Override
    public void run() {
        if(tag){
            while(true)
                ticks();
        }
        else{
            while (true) {
                synchronized (this) {
                    if (ticknumbers > 0) {
                        System.out.println(Thread.currentThread().getName() + "-->拿到了第" + ticknumbers-- + "票");//currentThread()監(jiān)測(cè)線程的狀態(tài)
                        try {
                            Thread.sleep(300);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    } else
                        break;
                }
            }
        }
    }

    //同步方法
    public synchronized void ticks() {
        if (ticknumbers > 0) {
            System.out.println(Thread.currentThread().getName() + "-->拿到了第" + ticknumbers-- + "票");
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        else
            return;
    }
}


    //測(cè)試類(lèi)
    class test {
        public static void main(String[] args) throws InterruptedException {
            Runnable_test runnable_test = new Runnable_test();
            Thread thread1=new Thread(runnable_test, "小明");
            thread1.start();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            runnable_test.tag=true;
            Thread thread2=new Thread(runnable_test, "小黃");
            thread2.start();
        }
    }

輸出:

小明-->拿到了第20票
小明-->拿到了第19票
小明-->拿到了第18票
小明-->拿到了第17票
小明-->拿到了第16票
小明-->拿到了第15票
小明-->拿到了第14票
小明-->拿到了第13票
小明-->拿到了第12票
小明-->拿到了第11票
小明-->拿到了第10票
小明-->拿到了第9票
小明-->拿到了第8票
小明-->拿到了第7票
小黃-->拿到了第6票
小黃-->拿到了第5票
小黃-->拿到了第4票
小黃-->拿到了第3票
小黃-->拿到了第2票
小黃-->拿到了第1票

通過(guò)程序運(yùn)行結(jié)果可以看出:線程thread1執(zhí)行同步代碼塊,線程thread2執(zhí)行同步方法,兩個(gè)線程之間形成了同步。

由于同步代碼塊是給 this對(duì)象加鎖,所以表明同步方法也是給 this對(duì)象加鎖,否則,兩者之間不能形成同步。

注意:多線程的同步程序中,不同的線程對(duì)象必須給同一個(gè)對(duì)象加鎖,否則這些線程對(duì)象之間無(wú)法實(shí)現(xiàn)同步

線程組

線程組可以看作是包含了許多線程的對(duì)象集,它擁有一個(gè)名字以及一些相關(guān)的屬性,可以當(dāng)作一個(gè)組來(lái)管理其中的線程。

每個(gè)線程都是線程組的一個(gè)成員,線程組把多個(gè)線程集成一個(gè)對(duì)象,通過(guò)線程組可以同時(shí)對(duì)其中的多個(gè)線程進(jìn)行操作。在生成線程時(shí)必須將線程放到指定的線程組,也可以放在缺省的線程組中,缺省的就是生成該線程的線程所在的線程組。一旦一個(gè)線程加入了某個(gè)線程組,就不能被移出這個(gè)組。

java,lang包的ThreadGroup類(lèi)表示線程組,在創(chuàng)建線程之前,可以創(chuàng)建一個(gè)ThreadGroup對(duì)象。

下面代碼是創(chuàng)建線程組并在其中加人兩個(gè)線程

ThreadGroup myThreadGroup = new ThreadGroup("a");    //創(chuàng)建線程組

//將下述兩個(gè)線程加入其中
Thread myThread1 = new Thread(myThreadGroup,"worker1");
Thread myThread2 = new Thread(myThreadGroup,"worker2");
myThread1.start();
myThread2.start();

線程組的相關(guān)方法

String getName();    //返回線程組的名字
ThreadGoup getParent();    //返回父線程
int tactiveCount();    //返回線程組中當(dāng)前激活的線程的數(shù)目,包括子線程組中的活動(dòng)線程
int enumerate(Thread list[])    //將所有線程組中激活的線程復(fù)制到一個(gè)線程數(shù)組中
void setMaxPriority(int pri)    //設(shè)置線程的最高優(yōu)先級(jí),pri是該線程組的新優(yōu)先級(jí)
void interrupt()    //向線程組及其子組中的線程發(fā)送一個(gè)中斷信息
boolean isDaemon()    //判斷是否為Daemon線程組
boolean parentOf(ThreadGoup g)    //判斷線程組是否是線程g或g的子線程
toString()    //返回一個(gè)表示本線程組的字符串 

線程組對(duì)象的基本應(yīng)用

舉例:

package Runnable;

public class MyThreadgroup {
    public void test(){
        ThreadGroup threadGroup=new ThreadGroup("test");    //創(chuàng)建名為test的線程組
        Thread A=new Thread(threadGroup,"線程A");
        Thread B=new Thread(threadGroup,"線程B");
        Thread C=new Thread(threadGroup,"線程C");

        //為線程設(shè)置優(yōu)先級(jí)
        A.setPriority(6);
        C.setPriority(4);
        A.start();
        B.start();
        C.start();
        System.out.println("threadGroup正在進(jìn)行活動(dòng)的個(gè)數(shù):"+threadGroup.activeCount());
        System.out.println("線程A的優(yōu)先級(jí):"+A.getPriority());
        System.out.println("線程B的優(yōu)先級(jí):"+B.getPriority());
        System.out.println("線程C的優(yōu)先級(jí):"+C.getPriority());
    }
}
class MyThreadgroup_test{
    public static void main(String[] args) {
       MyThreadgroup myThreadgroup=new MyThreadgroup();
       myThreadgroup.test();
    }
}

輸出:

threadGroup正在進(jìn)行活動(dòng)的個(gè)數(shù):3
線程A的優(yōu)先級(jí):6
線程B的優(yōu)先級(jí):5
線程C的優(yōu)先級(jí):4

線程間的通信

某些情況下,多個(gè)線程之間需要相互配合來(lái)完成一件事情,這些線程之間就需要進(jìn)行通信”,把一方線程的執(zhí)行情況告訴給另一方線程。

“通信”的方法在 java.lang.Object類(lèi)中定義了,我們可以通過(guò)“生產(chǎn)者-消費(fèi)者”模型來(lái)理解線程間的通信。

有兩個(gè)線程對(duì)象,其中一個(gè)是生產(chǎn)者,另一個(gè)是消費(fèi)者。生產(chǎn)者線程負(fù)責(zé)生產(chǎn)產(chǎn)品并放入產(chǎn)品緩沖區(qū),消費(fèi)者線程負(fù)責(zé)從產(chǎn)品緩沖區(qū)取出產(chǎn)品并消費(fèi)。

當(dāng)生產(chǎn)者線程獲得 CPU 使用權(quán)后:

先判斷產(chǎn)品緩沖區(qū)是否有產(chǎn)品,如果有產(chǎn)品就調(diào)用 wait()方法進(jìn)入產(chǎn)品緩沖區(qū)對(duì)象的等待隊(duì)列并釋放產(chǎn)品緩沖區(qū)對(duì)象的鎖;如果發(fā)現(xiàn)產(chǎn)品緩沖區(qū)中沒(méi)有產(chǎn)品,就生產(chǎn)產(chǎn)品并放入緩沖區(qū)并調(diào)用notify()方法發(fā)送通知給消費(fèi)者線程。

當(dāng)消費(fèi)者線程獲得CPU使用權(quán)后:

先判斷產(chǎn)品緩沖區(qū)是否有產(chǎn)品,如果有產(chǎn)品就拿出來(lái)消費(fèi)并調(diào)用 notify()方法發(fā)送通知給生產(chǎn)者線程;如果發(fā)現(xiàn)產(chǎn)品緩沖區(qū)中沒(méi)有產(chǎn)品,調(diào)用 wait()方法進(jìn)入產(chǎn)品緩沖區(qū)對(duì)象的等待隊(duì)列并釋放產(chǎn)品緩沖區(qū)對(duì)象的鎖。

注意:線程間通信是建立在線程同步基礎(chǔ)上的,所以wait()notify()和notifyAll()方法的調(diào)用要出現(xiàn)在同步代碼塊或同步方法中

線程通信簡(jiǎn)單應(yīng)用

package Runnable;


 class Box {//產(chǎn)品緩沖區(qū)
    public String name="蘋(píng)果";//表示產(chǎn)品的名稱(chēng)
    public boolean isFull=true;//表示當(dāng)前緩沖區(qū)中是否有產(chǎn)品
}



//定義消費(fèi)者類(lèi)
class Cossumer implements Runnable {
    Box box;

    Cossumer(Box box) {
        this.box = box;
    }

    @Override
    public void run() {
        while (true) {
            synchronized (box) {//對(duì)產(chǎn)品緩沖區(qū)對(duì)象加鎖
                if (box.isFull == true) //緩沖區(qū)中有產(chǎn)品
                {
                    System.out.println("消費(fèi)者拿出----:" + box.name);
                    box.isFull = false;//設(shè)置緩沖區(qū)中產(chǎn)品為空
                    box.notify();//發(fā)送通知給生產(chǎn)者線程對(duì)象
                } else {
                    try {
                        //消費(fèi)者線程進(jìn)入產(chǎn)品緩沖區(qū)的等待隊(duì)列并釋放鎖
                        box.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}



    //生產(chǎn)者類(lèi)
    class product implements Runnable{
        Box box;
        int Count=0;

        public product(Box box) {
            this.box=box;
        }

        @Override
        public void run() {
            while(true){
                synchronized (box)//對(duì)產(chǎn)品緩沖區(qū)對(duì)象加鎖
                {
                    if(box.isFull==true)//緩沖區(qū)中有產(chǎn)品
                    {
                        try {
                            box.wait();//生產(chǎn)者線程進(jìn)入等待隊(duì)列并釋放鎖
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    else {
                        if (Count == 0) {
                            box.name = "香蕉";
                            System.out.println("生產(chǎn)者放入+++++:" + box.name);
                        } else {
                            box.name = "蘋(píng)果";
                            System.out.println("生產(chǎn)者放入+++++:" + box.name);
                        }
                        Count=(Count+1)%2;
                        box.isFull=true;//設(shè)置緩沖區(qū)中有產(chǎn)品
                        box.notify();//發(fā)送通知給消費(fèi)者線程對(duì)象
                    }
                }
            }
        }
    }


class box_test{
    public static void main(String[] args) {
        Box box=new Box();//創(chuàng)建產(chǎn)品緩沖區(qū)對(duì)象
        product product=new product(box);

        Cossumer cossumer=new Cossumer(box);//生產(chǎn)者和消費(fèi)者對(duì)象要共享同一個(gè)產(chǎn)品緩沖區(qū)
        Thread thread1=new Thread(product);//創(chuàng)建生產(chǎn)者線程對(duì)象
        Thread thread2=new Thread(cossumer);//創(chuàng)建消費(fèi)者線程對(duì)象
        thread1.start();//啟動(dòng)生產(chǎn)者線程對(duì)象
        thread2.start();//啟動(dòng)消費(fèi)者線程對(duì)象
    }
}

輸出:

消費(fèi)者拿出----:香蕉
生產(chǎn)者放入+++++:蘋(píng)果
消費(fèi)者拿出----:蘋(píng)果
生產(chǎn)者放入+++++:香蕉
消費(fèi)者拿出----:香蕉
生產(chǎn)者放入+++++:蘋(píng)果
消費(fèi)者拿出----:蘋(píng)果
生產(chǎn)者放入+++++:香蕉
消費(fèi)者拿出----:香蕉
生產(chǎn)者放入+++++:蘋(píng)果
消費(fèi)者拿出----:蘋(píng)果
生產(chǎn)者放入+++++:香蕉

從運(yùn)行結(jié)果可以看出:生產(chǎn)者線程向緩沖區(qū)放入什么產(chǎn)品,消費(fèi)者就從緩沖區(qū)中取出什么產(chǎn)品,生產(chǎn)者生產(chǎn)一個(gè)產(chǎn)品,消費(fèi)者就消費(fèi)一個(gè)產(chǎn)品,兩者之間實(shí)現(xiàn)了通信.

以上就是Java學(xué)習(xí)之線程同步與線程間通信詳解的詳細(xì)內(nèi)容,更多關(guān)于Java線程的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • java開(kāi)發(fā)BeanUtils類(lèi)解決實(shí)體對(duì)象間賦值

    java開(kāi)發(fā)BeanUtils類(lèi)解決實(shí)體對(duì)象間賦值

    這篇文章主要為大家介紹了java開(kāi)發(fā)中使用BeanUtils類(lèi)實(shí)現(xiàn)實(shí)體對(duì)象之間的賦值有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步學(xué)有所得
    2021-10-10
  • SpringCloud?Gateway詳細(xì)分析實(shí)現(xiàn)負(fù)載均衡與熔斷和限流

    SpringCloud?Gateway詳細(xì)分析實(shí)現(xiàn)負(fù)載均衡與熔斷和限流

    這篇文章主要介紹了SpringCloud?Gateway實(shí)現(xiàn)路由轉(zhuǎn)發(fā),負(fù)載均衡,熔斷和限流,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-07-07
  • Collection中的size()和isEmpty()區(qū)別說(shuō)明

    Collection中的size()和isEmpty()區(qū)別說(shuō)明

    這篇文章主要介紹了Collection中的size()和isEmpty()區(qū)別說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • Mybatis一對(duì)多與多對(duì)一查詢(xún)處理詳解

    Mybatis一對(duì)多與多對(duì)一查詢(xún)處理詳解

    這篇文章主要給大家介紹了關(guān)于Mybatis一對(duì)多與多對(duì)一查詢(xún)處理的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • Java去掉小數(shù)點(diǎn)后面無(wú)效0的方案與建議

    Java去掉小數(shù)點(diǎn)后面無(wú)效0的方案與建議

    當(dāng)前小數(shù)點(diǎn)后面的位數(shù)過(guò)多的時(shí)候,多余的0沒(méi)有實(shí)際意義,下面這篇文章主要給大家介紹了關(guān)于Java去掉小數(shù)點(diǎn)后面無(wú)效0的方案與建議,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-07-07
  • ?java簡(jiǎn)介及環(huán)境搭建

    ?java簡(jiǎn)介及環(huán)境搭建

    這篇文章主要介紹了java簡(jiǎn)介及環(huán)境搭建,文章主要介紹Java的發(fā)展史及環(huán)境搭建,對(duì)正在學(xué)Java的你有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-03-03
  • mybatis-generator如何自定義注釋生成

    mybatis-generator如何自定義注釋生成

    這篇文章主要介紹了mybatis-generator如何自定義注釋生成的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • SpringBoot雪花算法主鍵ID傳到前端后精度丟失問(wèn)題的解決

    SpringBoot雪花算法主鍵ID傳到前端后精度丟失問(wèn)題的解決

    本文主要介紹了SpringBoot雪花算法主鍵ID傳到前端后精度丟失問(wèn)題的解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • Mybatis控制臺(tái)打印Sql語(yǔ)句的實(shí)現(xiàn)代碼

    Mybatis控制臺(tái)打印Sql語(yǔ)句的實(shí)現(xiàn)代碼

    MyBatis是一個(gè)支持普通SQL查詢(xún),存儲(chǔ)過(guò)程和高級(jí)映射的優(yōu)秀持久層框架,下面給大家介紹Mybatis控制臺(tái)打印Sql語(yǔ)句的實(shí)現(xiàn)代碼,非常不錯(cuò),感興趣的朋友一起看下吧
    2016-07-07
  • Spring?Cache注解@Cacheable的九個(gè)屬性詳解

    Spring?Cache注解@Cacheable的九個(gè)屬性詳解

    在@Cacheable注解的使用中,共有9個(gè)屬性供我們來(lái)使用,這9個(gè)屬性分別是:value、?cacheNames、?key、?keyGenerator、?cacheManager、?cacheResolver、?condition、?unless、?sync,下面介紹@Cacheable注解屬性使用方法,感興趣的朋友一起看看吧
    2025-05-05

最新評(píng)論