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

Java zookeeper服務(wù)的使用詳解

 更新時(shí)間:2022年08月01日 15:44:25   作者:kaico2018  
ZooKeeper是一個(gè)分布式的,開(kāi)放源碼的分布式應(yīng)用程序協(xié)調(diào)服務(wù),是Google的Chubby一個(gè)開(kāi)源的實(shí)現(xiàn),是Hadoop和Hbase的重要組件。它是一個(gè)為分布式應(yīng)用提供一致性服務(wù)的軟件,提供的功能包括:配置維護(hù)、域名服務(wù)、分布式同步、組服務(wù)等

Java語(yǔ)言客戶端使用zookeeper

下載zookeeper連接工具,方便我們查看zookeeper存的數(shù)據(jù)。下載地址:

https://pan.baidu.com/s/1UG5_VcYUZUYUkg04QROLYg?pwd=3ych 提取碼: 3ych

下載后解壓就可以使用了:

使用頁(yè)面:

Java語(yǔ)言連接z00keeper

首先引入maven 依賴jar包

<dependency>
	<groupId>com.101tec</groupId>
	<artifactId>zkclient</artifactId>
	<version>0.9</version>
</dependency>

編寫(xiě)Java代碼

public class Test001 {
    private static final String ADDRES = "127.0.0.1:2181";
    private static final int TIMAOUT = 5000;
    //計(jì)數(shù)器
    private static CountDownLatch countDownLatch = new CountDownLatch(1);
    public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
        //zk核心節(jié)點(diǎn)+事件通知
        //節(jié)點(diǎn)路徑和界定啊value
        /**
         * 參數(shù)一:連接地址
         * 參數(shù)二:zk超時(shí)時(shí)間
         * 參數(shù)三:事件通知
         */
        //1、創(chuàng)建zk鏈接
        ZooKeeper zooKeeper = new ZooKeeper(ADDRES, TIMAOUT, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                Event.KeeperState state = watchedEvent.getState();
                if(state == Event.KeeperState.SyncConnected){
                    System.out.println("zk鏈接成功");
                    countDownLatch.countDown(); //計(jì)數(shù)器減 1
                }
            }
        });
        //計(jì)數(shù)器結(jié)果必須是為0 才能繼續(xù)執(zhí)行
        System.out.println("zk正在等待連接");
        countDownLatch.await();
        System.out.println("開(kāi)始創(chuàng)建我們的連接");
        //2、創(chuàng)建我們的節(jié)點(diǎn)
        /**
         * 參數(shù)一:路徑名稱
         * 參數(shù)二:節(jié)點(diǎn)value
         * 參數(shù)三:節(jié)點(diǎn)權(quán)限acl
         * 蠶食四:節(jié)點(diǎn)類型 臨時(shí)和永久
         */
        String s = zooKeeper.create("/kaico/one", "hello,boy".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
        System.out.println(s);
        zooKeeper.close();
    }
}

可以利用連接工具查看操作結(jié)果。

zooKeeper類有很多api操作節(jié)點(diǎn),可以創(chuàng)建、刪除。

zookeeper Javaapi文檔: 點(diǎn)擊查看

四種節(jié)點(diǎn)類型

第一種:臨時(shí)節(jié)點(diǎn):會(huì)話關(guān)閉之后,就自動(dòng)消失 CreateMode.PERSISTENT_SEQUENTIAL

第二種:臨時(shí)有序節(jié)點(diǎn) CreateMode.EPHEMERAL

第三種:持久節(jié)點(diǎn):會(huì)話關(guān)閉之后,持久化到硬盤(pán) CreateMode.PERSISTENT

第四種:持久有序節(jié)點(diǎn) CreateMode.PERSISTENT_SEQUENTIAL

ACL權(quán)限

ACL權(quán)限模型,實(shí)際上就是對(duì)樹(shù)每個(gè)節(jié)點(diǎn)實(shí)現(xiàn)控制.

身份的認(rèn)證有4種方式:

world:默認(rèn)方式,相當(dāng)于全世界都能訪問(wèn).

auth:代表已經(jīng)認(rèn)證通過(guò)的用戶(cli中可以通過(guò)addauth digest user:pwd來(lái)添加當(dāng)前上下文中的授權(quán)用戶).

digest:即用戶名:密碼這種方式認(rèn)證,這也是業(yè)務(wù)系統(tǒng)中最常用的.

ip:使用lp地址認(rèn)證。

代碼案例:使用賬號(hào)密碼實(shí)現(xiàn)權(quán)限控制

1、添加有權(quán)限控制的節(jié)點(diǎn)數(shù)據(jù)

public class Test002 {
    private static final String ADDRES = "127.0.0.1:2181";
    private static final int TIMAOUT = 5000;
    //計(jì)數(shù)器
    private static CountDownLatch countDownLatch = new CountDownLatch(1);
    public static void main(String[] args) throws IOException, InterruptedException, KeeperException, NoSuchAlgorithmException {
        /**
         * 參數(shù)一:連接地址
         * 參數(shù)二:zk超時(shí)時(shí)間
         * 參數(shù)三:事件通知
         */
        //1、創(chuàng)建zk鏈接
        ZooKeeper zooKeeper = new ZooKeeper(ADDRES, TIMAOUT, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                Event.KeeperState state = watchedEvent.getState();
                if(state == Event.KeeperState.SyncConnected){
                    System.out.println("zk鏈接成功");
                    countDownLatch.countDown(); //計(jì)數(shù)器減 1
                }
            }
        });
        //計(jì)數(shù)器結(jié)果必須是為0 才能繼續(xù)執(zhí)行
        System.out.println("zk正在等待連接");
        countDownLatch.await();
        System.out.println("開(kāi)始創(chuàng)建我們的連接");
        //創(chuàng)建賬號(hào) admin 可以實(shí)現(xiàn)讀寫(xiě)操作
        Id admin = new Id("digest", DigestAuthenticationProvider.generateDigest("admin:admin123"));
        ACL acl1 = new ACL(ZooDefs.Perms.ALL, admin);
        //創(chuàng)建賬號(hào) guest 只允許做讀操作
        Id guest = new Id("digest", DigestAuthenticationProvider.generateDigest("guest:guest123"));
        ACL acl2 = new ACL(ZooDefs.Perms.READ, guest);
        ArrayList<ACL> acls = new ArrayList<>();
        acls.add(acl1);
        acls.add(acl2);
        //2、創(chuàng)建我們的節(jié)點(diǎn)
        /**
         * 參數(shù)一:路徑名稱
         * 參數(shù)二:節(jié)點(diǎn)value
         * 參數(shù)三:節(jié)點(diǎn)權(quán)限acl
         * 蠶食四:節(jié)點(diǎn)類型 臨時(shí)和永久
         */
        String s = zooKeeper.create("/kaico/acl", "hello,boy".getBytes(), acls, CreateMode.PERSISTENT);
        System.out.println(s);
        zooKeeper.close();
    }
}

2、獲取設(shè)置了權(quán)限的節(jié)點(diǎn)數(shù)據(jù)

public class Test003 {
    private static final String ADDRES = "127.0.0.1:2181";
    private static final int TIMAOUT = 5000;
    //計(jì)數(shù)器
    private static CountDownLatch countDownLatch = new CountDownLatch(1);
    public static void main(String[] args) throws IOException, InterruptedException, KeeperException, NoSuchAlgorithmException {
        /**
         * 參數(shù)一:連接地址
         * 參數(shù)二:zk超時(shí)時(shí)間
         * 參數(shù)三:事件通知
         */
        //1、創(chuàng)建zk鏈接
        ZooKeeper zooKeeper = new ZooKeeper(ADDRES, TIMAOUT, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                Event.KeeperState state = watchedEvent.getState();
                if(state == Event.KeeperState.SyncConnected){
                    System.out.println("zk鏈接成功");
                    countDownLatch.countDown(); //計(jì)數(shù)器減 1
                }
            }
        });
        //計(jì)數(shù)器結(jié)果必須是為0 才能繼續(xù)執(zhí)行
        System.out.println("zk正在等待連接");
        countDownLatch.await();
        System.out.println("開(kāi)始創(chuàng)建我們的連接");
        //設(shè)置一下zookeeper 的賬號(hào)才有權(quán)限獲取內(nèi)容
        zooKeeper.addAuthInfo("digest", "guest:guest123".getBytes());
        //獲取節(jié)點(diǎn)的內(nèi)容
        byte[] data = zooKeeper.getData("/kaico/acl", null, new Stat());
        System.out.println(new String(data));
        zooKeeper.close();
    }
}

實(shí)現(xiàn)事件監(jiān)聽(tīng)通知

Zookeeper實(shí)現(xiàn)基本的總結(jié):類似于文件存儲(chǔ)系統(tǒng),可以幫助我們解決分布式領(lǐng)域中遇到問(wèn)題

Zookeeper分布式協(xié)調(diào)工具

特征:

  • 定義的節(jié)點(diǎn)包含key (路徑)和 value ,路徑不允許有重復(fù)保證唯一性.
  • Zookeeper分為四種類型持久、持久序號(hào)、臨時(shí)、臨時(shí)序號(hào).
  • 持久與臨時(shí)節(jié)點(diǎn)區(qū)別:連接如果一旦關(guān)閉,當(dāng)前的節(jié)點(diǎn)自動(dòng)刪除;
  • 事件通知監(jiān)聽(tīng)節(jié)點(diǎn)發(fā)生的變化刪除、修改、子節(jié)點(diǎn)

Java代碼案例:

public class Test004 {
    private static final String ADDRES = "127.0.0.1:2181";
    private static final int TIMAOUT = 5000;
    //計(jì)數(shù)器
    private static CountDownLatch countDownLatch = new CountDownLatch(1);
    public static void main(String[] args) throws IOException, InterruptedException, KeeperException, NoSuchAlgorithmException {
        //1、創(chuàng)建zk 連接
        ZkClient zkClient = new ZkClient(ADDRES, TIMAOUT);
        String parentPath = "/kaico/jing";
        //2、監(jiān)聽(tīng)節(jié)點(diǎn)發(fā)生的變化,監(jiān)聽(tīng)子節(jié)點(diǎn)是否發(fā)生變化,如果發(fā)生變化都可以獲取到回調(diào)通知。
//        zkClient.subscribeChildChanges(parentPath, new IZkChildListener() {
//            @Override
//            public void handleChildChange(String s, List<String> list) throws Exception {
//                System.out.println("s:" + s + ",節(jié)點(diǎn)發(fā)生了變化");
//                list.forEach((t)->{
//                    System.out.println("子節(jié)點(diǎn):" + t);
//                });
//            }
//        });
        //監(jiān)聽(tīng)節(jié)點(diǎn)的內(nèi)容是否發(fā)生變化或刪除
        zkClient.subscribeDataChanges(parentPath, new IZkDataListener() {
            @Override
            public void handleDataChange(String s, Object o) throws Exception {
                System.out.println("修改的節(jié)點(diǎn)為:" + s + ",修改之后的值:" + o);
            }
            @Override
            public void handleDataDeleted(String s) throws Exception {
                System.out.println("節(jié)點(diǎn):" + s + "被刪除");
            }
        });
        //修改值內(nèi)容
        zkClient.writeData(parentPath, "666666666666666");
        while (true){
        }
//        zkClient.close();
    }
}

微服務(wù)使用zookeeper作為注冊(cè)中心

調(diào)用接口邏輯圖

使用zookeeper實(shí)現(xiàn)邏輯:

根據(jù)服務(wù)提供方的名稱創(chuàng)建對(duì)應(yīng)的節(jié)點(diǎn),服務(wù)提供方的接口所有的ip+端口作為子節(jié)點(diǎn)的value的值,這樣服務(wù)調(diào)用方根據(jù)服務(wù)提供方的名稱在zookeeper上找到對(duì)應(yīng)的ip+端口從而可以調(diào)用對(duì)應(yīng)的接口,再監(jiān)聽(tīng)該節(jié)點(diǎn),如果提供接口的機(jī)器發(fā)生宕機(jī)于zookeeper斷開(kāi)連接,子節(jié)點(diǎn)也相應(yīng)的減少了,服務(wù)調(diào)用方也會(huì)收到通知。

分布式鎖

分布式鎖的概念:解決再多個(gè)jvm中最終只能有一個(gè)jvm 執(zhí)行。

zookeeper實(shí)現(xiàn)分布式鎖的思路:

節(jié)點(diǎn)保證唯一、事件通知、臨時(shí)節(jié)點(diǎn)(生命周期和Session會(huì)關(guān)聯(lián))﹒

創(chuàng)建分布式鎖原理:

1.多個(gè)jvm同時(shí)在Zookeeper 上創(chuàng)建相同的臨時(shí)節(jié)點(diǎn)(lockPath).

2. 因?yàn)榕R時(shí)節(jié)點(diǎn)路徑保證唯一的性,只要誰(shuí)能夠創(chuàng)建成功誰(shuí)就能夠獲取鎖,就可以開(kāi)始執(zhí)

行業(yè)務(wù)邏輯;,

3.如果節(jié)點(diǎn)已經(jīng)給其他請(qǐng)求創(chuàng)建的話或者是創(chuàng)建節(jié)點(diǎn)失敗,當(dāng)前的請(qǐng)求實(shí)現(xiàn)等待;

釋放鎖的原理

因?yàn)槲覀儾捎门R時(shí)節(jié)點(diǎn),當(dāng)前節(jié)點(diǎn)創(chuàng)建成功,表示獲取鎖成功;正常執(zhí)行完業(yè)務(wù)邏輯調(diào)用Session關(guān)閉連接方法,當(dāng)前的節(jié)點(diǎn)會(huì)刪除;----釋放鎖

其他正在等待請(qǐng)求,采用事件監(jiān)聽(tīng)如果當(dāng)前節(jié)點(diǎn)被刪除的話,又重新進(jìn)入到獲取鎖流程;

臨時(shí)節(jié)點(diǎn)+事件通知。

代碼實(shí)現(xiàn)分布式鎖

實(shí)現(xiàn)分布式鎖的方式有多種:數(shù)據(jù)庫(kù)、redis、zookeeper,這里使用zookeeper實(shí)現(xiàn)。

實(shí)現(xiàn)原理:

因?yàn)閆ookeeper節(jié)點(diǎn)路徑保持唯一,不允許重復(fù) 且有臨時(shí)節(jié)點(diǎn)特性連接關(guān)閉后當(dāng)前節(jié)點(diǎn)會(huì)自動(dòng)消失,從而實(shí)現(xiàn)分布式鎖。

  • 多請(qǐng)求同時(shí)創(chuàng)建相同的節(jié)點(diǎn)(lockPath),只要誰(shuí)能夠創(chuàng)建成功 誰(shuí)就能夠獲取到鎖;
  • 如果創(chuàng)建節(jié)點(diǎn)的時(shí)候,突然該節(jié)點(diǎn)已經(jīng)被其他請(qǐng)求創(chuàng)建的話則直接等待;
  • 只要能夠創(chuàng)建節(jié)點(diǎn)成功,則開(kāi)始進(jìn)入到正常業(yè)務(wù)邏輯操作,其他沒(méi)有獲取鎖進(jìn)行等待;
  • 正常業(yè)務(wù)邏輯流程執(zhí)行完后,調(diào)用zk關(guān)閉連接方式釋放鎖,從而是其他的請(qǐng)求開(kāi)始進(jìn)入到獲取鎖的資源。

使用zookeeper 實(shí)現(xiàn)分們式鎖的代碼案例

利用模板設(shè)計(jì)模式實(shí)現(xiàn)分布式鎖

1、定義鎖接口 Lock

public interface Lock {
    /**
     * 獲取鎖
     */
    public void getLock();
    /**
     * 釋放鎖
     */
    public void unLock();
}

2、定義抽象類實(shí)現(xiàn)鎖接口 Lock ,設(shè)計(jì)其他的方法完成對(duì)鎖的操作

abstract class AbstractTemplzateLock implements Lock {
    @Override
    public void getLock() {
        // 模版方法 定義共同抽象的骨架
        if (tryLock()) {
            System.out.println(">>>" + Thread.currentThread().getName() + ",獲取鎖成功");
        } else {
            // 開(kāi)始實(shí)現(xiàn)等待
            waitLock();// 事件監(jiān)聽(tīng)
            // 重新獲取
            getLock();
        }
    }
    /**
     * 獲取鎖
     * @return
     */
    protected abstract boolean tryLock();
    /**
     * 等待鎖
     * @return
     */
    protected abstract void waitLock();
    /**
     * 釋放鎖
     * @return
     */
    protected abstract void unImplLock();
    @Override
    public void unLock() {
        unImplLock();
    }
}

3、利用zookeeper實(shí)現(xiàn)鎖,繼承抽象類 AbstractTemplzateLock

public class ZkTemplzateImplLock extends AbstractTemplzateLock {
    //參數(shù)1 連接地址
    private static final String ADDRES = "192.168.212.147:2181";
    // 參數(shù)2 zk超時(shí)時(shí)間
    private static final int TIMEOUT = 5000;
    // 創(chuàng)建我們的zk連接
    private ZkClient zkClient = new ZkClient(ADDRES, TIMEOUT);
    /**
     * 共同的創(chuàng)建臨時(shí)節(jié)點(diǎn)
     */
    private String lockPath = "/lockPath";
    private CountDownLatch countDownLatch = null;
    @Override
    protected boolean tryLock() {
        // 獲取鎖的思想:多個(gè)jvm同時(shí)創(chuàng)建臨時(shí)節(jié)點(diǎn),只要誰(shuí)能夠創(chuàng)建成功 誰(shuí)能夠獲取到鎖
        try {
            zkClient.createEphemeral(lockPath);
            return true;
        } catch (Exception e) {
//            // 如果創(chuàng)建已經(jīng)存在的話
//            e.printStackTrace();
            return false;
        }
    }
    @Override
    protected void waitLock() {
        // 1.使用事件監(jiān)聽(tīng) 監(jiān)聽(tīng)lockPath節(jié)點(diǎn)是否已經(jīng)被刪除,如果被刪除的情況下 有可以重新的進(jìn)入到獲取鎖的權(quán)限
        IZkDataListener iZkDataListener = new IZkDataListener() {
            @Override
            public void handleDataChange(String s, Object o) throws Exception {
            }
            @Override
            public void handleDataDeleted(String s) throws Exception {
                if (countDownLatch != null) {
                    countDownLatch.countDown();// 計(jì)數(shù)器變?yōu)?
                }
            }
        };
        zkClient.subscribeDataChanges(lockPath, iZkDataListener);
        // 2.使用countDownLatch等待
        if (countDownLatch == null) {
            countDownLatch = new CountDownLatch(1);
        }
        try {
            countDownLatch.await();// 如果當(dāng)前計(jì)數(shù)器不是為0 就一直等待
        } catch (Exception e) {
        }
        // 3. 如果當(dāng)前節(jié)點(diǎn)被刪除的情況下,有需要重新進(jìn)入到獲取鎖
        zkClient.unsubscribeDataChanges(lockPath, iZkDataListener);
    }
    @Override
    protected void unImplLock() {
        if (zkClient != null) {
            zkClient.close();
            System.out.println(Thread.currentThread().getName() + ",釋放了鎖>>>");
        }
    }
}

4、編寫(xiě)使用鎖的方法

//main方法使用多線程測(cè)試分布式鎖
  public static void main(String[] args) {
//        OrderService orderService = new OrderService();
        for (int i = 0; i < 100; i++) {
            new Thread(new OrderService()).start();
        }
        // 單個(gè)jvm中多線程同時(shí)生成訂單號(hào)碼如果發(fā)生重復(fù) 如何解決 synchronized或者是lock鎖
        // 如果在多個(gè)jvm中同時(shí)生成訂單號(hào)碼如果發(fā)生重復(fù)如何解決
        // 注意synchronized或者是lock鎖 只能夠在本地的jvm中有效
        // 分布式鎖的概念
    }
//多線程run 方法
public class OrderService implements Runnable {
    private OrderNumGenerator orderNumGenerator = new OrderNumGenerator();
    private Lock lock = new ZkTemplzateImplLock();
    @Override
    public void run() {
        getNumber();
    }
    private void getNumber() {
        try {
            lock.getLock();
            Thread.sleep(50);
            String number = orderNumGenerator.getNumber();
            System.out.println(Thread.currentThread().getName() + ",獲取的number:" + number);
            // 如果zk超時(shí)了,有做數(shù)據(jù)庫(kù)寫(xiě)的操作統(tǒng)一直接回滾
        } catch (Exception e) {

        } finally {
            lock.unLock();
        }
    }
    // ZkTemplzateImplLock父親 模版類 AbstractTemplzateLock 父親  Lock
}
//自動(dòng)生成訂單號(hào)的類
public class OrderNumGenerator {
    /**
     * 序號(hào)
     */
    private static int count;
    /**
     * 生成我們的時(shí)間戳 為訂單號(hào)碼
     * @return
     */
    public String getNumber() {
        SimpleDateFormat simpt = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
        try {
            Thread.sleep(30);
        } catch (Exception e) {
        }
        return simpt.format(new Date()) + "-" + ++count;
    }
}

如何防止死鎖?

創(chuàng)建zkClient時(shí)設(shè)置session 連接時(shí)間 sessionTimeout。 也就是設(shè)置Session連接超時(shí)時(shí)間,在規(guī)定的時(shí)間內(nèi)獲取鎖后超時(shí)啦~自動(dòng)回滾當(dāng)前數(shù)據(jù)庫(kù)業(yè)務(wù)邏輯。

注意:等待鎖時(shí),zkClient注冊(cè)的事件最后需要?jiǎng)h除。

到此這篇關(guān)于Java zookeeper服務(wù)的使用詳解的文章就介紹到這了,更多相關(guān)Java zookeeper服務(wù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java背包問(wèn)題求解實(shí)例代碼

    Java背包問(wèn)題求解實(shí)例代碼

    這篇文章主要介紹了Java背包問(wèn)題求解實(shí)例代碼,其中涉及兩種背包:01和完全背包。分別講述了兩種背包的思路和實(shí)現(xiàn)方法,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-10-10
  • Java 中的 getDeclaredMethods() 方法(使用與原理)

    Java 中的 getDeclaredMethods() 方法(使用與原理)

    文章介紹了Java反射機(jī)制中的`getDeclaredMethods()`方法,詳細(xì)講解了其使用方法、原理、注意事項(xiàng)以及實(shí)際應(yīng)用場(chǎng)景,幫助讀者更好地理解和應(yīng)用這一強(qiáng)大的工具,感興趣的朋友一起看看吧
    2024-12-12
  • spring boot 實(shí)現(xiàn)Minio分片上傳的步驟

    spring boot 實(shí)現(xiàn)Minio分片上傳的步驟

    分片上傳,就是將所要上傳的文件,按照一定的大小,將整個(gè)文件分隔成多個(gè)數(shù)據(jù)塊來(lái)進(jìn)行分別上傳,上傳完之后再由服務(wù)端對(duì)所有上傳的文件進(jìn)行匯總整合成原始的文件,本文給大家介紹spring boot 實(shí)現(xiàn)Minio分片上傳的步驟,感興趣的朋友跟隨小編一起看看吧
    2023-10-10
  • SpringBoot實(shí)現(xiàn)上傳文件到AWS S3的代碼

    SpringBoot實(shí)現(xiàn)上傳文件到AWS S3的代碼

    這篇文章主要介紹了SpringBoot實(shí)現(xiàn)上傳文件到AWS S3的代碼,幫助大家更好的理解和使用springboot框架,感興趣的朋友可以了解下
    2020-10-10
  • SpringCloud中Sentinel基礎(chǔ)場(chǎng)景和異常處理方式

    SpringCloud中Sentinel基礎(chǔ)場(chǎng)景和異常處理方式

    這篇文章主要介紹了SpringCloud中Sentinel基礎(chǔ)場(chǎng)景和異常處理方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • 使用Spring Boot集成FastDFS的示例代碼

    使用Spring Boot集成FastDFS的示例代碼

    本篇文章主要介紹了使用Spring Boot集成FastDFS的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-02-02
  • Spring實(shí)現(xiàn)一個(gè)簡(jiǎn)單的SpringIOC容器

    Spring實(shí)現(xiàn)一個(gè)簡(jiǎn)單的SpringIOC容器

    本篇文章主要介紹了Spring實(shí)現(xiàn)一個(gè)簡(jiǎn)單的SpringIOC容器,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。
    2017-04-04
  • 詳解Java Bellman-Ford算法原理及實(shí)現(xiàn)

    詳解Java Bellman-Ford算法原理及實(shí)現(xiàn)

    Bellman-Ford算法與Dijkstra算法類似,都是以松弛操作作為基礎(chǔ),Bellman-Ford算法是對(duì)所有邊都進(jìn)行松弛操作,本文將詳解Bellman-Ford算法原理及實(shí)現(xiàn),感興趣的可以了解一下
    2022-07-07
  • Mybatis?Plus批處理操作的實(shí)現(xiàn)示例

    Mybatis?Plus批處理操作的實(shí)現(xiàn)示例

    MyBatis?Plus?提供了強(qiáng)大的批處理支持,可以幫助我們高效地處理大規(guī)模數(shù)據(jù),本文主要介紹了Mybatis?Plus批處理操作的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-07-07
  • Java線程間協(xié)作wait、notify和notifyAll詳解

    Java線程間協(xié)作wait、notify和notifyAll詳解

    這篇文章主要介紹了Java線程間協(xié)作wait、notify和notifyAll詳解,在 Java 中可以用 wait、notify 和 notifyAll 來(lái)實(shí)現(xiàn)線程間的通信,盡管關(guān)于wait和notify的概念很基礎(chǔ),它們也都是Object類的函數(shù),但用它們來(lái)寫(xiě)代碼卻并不簡(jiǎn)單,,需要的朋友可以參考下
    2023-10-10

最新評(píng)論

贵港市| 嘉义县| 长海县| 金阳县| 贡山| 阿城市| 清流县| 从化市| 澄迈县| 邹城市| 万源市| 章丘市| 客服| 长治市| 会泽县| 博兴县| 辽阳县| 南丹县| 绩溪县| 海原县| 公安县| 景宁| 六盘水市| 乌鲁木齐县| 溧水县| 沽源县| 濉溪县| 水城县| 鸡泽县| 册亨县| 长白| 成安县| 温泉县| 洪泽县| 祁门县| 瓦房店市| 吴忠市| 武穴市| 盈江县| 武平县| 莱州市|