day20-网络

Day20-网络


1. 线程(续)

juc 中的大部分类是通过无锁并发实现的(没有用synchronized)

CAS 机制 compare And swap 比较并交换

synchronized 可以称之为悲观锁
cas 体现的是乐观锁
首先不会给共享资源加锁,而是做一个尝试
先拿到旧值,查看旧值是否跟共享区域的值相等
如果不等,那么说明别的线程改动了共享区域的值,我的修改失败
如果相等,那么就让我的修改成功
如果修改失败,没关系,重新尝试

    int var5;
       // 修改失败,没关系,重新尝试 自旋
        do {
           // 获取共享区域的最新值
            var5 = this.getIntVolatile(var1, var2); // 10
                    // 比较并交换                                      最新值   最新值+1
        } while(! this.compareAndSwapInt(var1, var2, var5, var5 + var4));

        return var5;

1. 重入锁 ReentrantLock

.lock() 加锁
.unlock() 解锁
例子:

static int i = 0;

public static void main(String[] args) throws InterruptedException {
    ReentrantLock rl = new ReentrantLock();

    Thread t1 = new Thread(() -> {
        for (int j = 0; j < 5000; j++) {
            try {
                rl.lock(); // 加锁
                i++;
            } finally {
                rl.unlock(); // 保证解锁一定被执行
            }
        }
    });

    Thread t2 = new Thread(() -> {
        for (int j = 0; j < 5000; j++) {
            try {
                rl.lock(); // 加锁
                i--;
            } finally {
                rl.unlock(); // 保证解锁一定被执行
            }
        }
    });

    t1.start();
    t2.start();
    t1.join();
    t2.join();
    System.out.println(i);
}

synchronized 性能上比较 ReentrantLock 在高并发下低,ReentrantLock的内存占用会高一些

2. CountDownLatch

countdown 倒计时

当希望多个线程执行完毕后,再接着做下一步操作时,
例子:

public static void main(String[] args) throws InterruptedException {
    CountDownLatch cdl = new CountDownLatch(3);// 构造方法需要指定倒计时的数字
    new Thread(()->{
        System.out.println("线程1开始运行"+new Date());
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("线程1准备完成"+new Date());
        cdl.countDown();
    }).start();
    new Thread(()->{
        System.out.println("线程2开始运行"+new Date());
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("线程2准备完成"+new Date());
        cdl.countDown();
    }).start();
    new Thread(()->{
        System.out.println("线程3开始运行"+new Date());
        try {
            Thread.sleep(1500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("线程3准备完成"+new Date());
        cdl.countDown();
    }).start();

    // 主线程等待,直到倒计时为0
    System.out.println("主线程等待");
    cdl.await();
    System.out.println("ready go....");
}

一个应用例子:模拟10个玩家加载进度

public static void main(String[] args) throws InterruptedException {
    CountDownLatch latch = new CountDownLatch(10);
    String[] all = new String[10];

    for (int j = 0; j < 10; j++) {
        int x = j;
        new Thread(()->{
            Random r = new Random();
            for (int i = 0; i <= 100; i++) {
                try {
                    Thread.sleep(r.nextInt(100));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (all){
                    all[x]=(i+"%");
                    System.out.print("\r"+Arrays.toString(all));
                }
            }
            latch.countDown();

        }).start();
    }

    latch.await();
    System.out.println("\nend...");
}

3. 循环栅栏

// CyclicBarrier   可循环的 屏障(栅栏)
// 当满足CyclicBarrier设置的线程个数时,继续执行,没有满足则等待
CyclicBarrier cb = new CyclicBarrier(2); // 个数为2时才会继续执行

new Thread(()->{
    System.out.println("线程1开始.."+new Date());
    try {
        cb.await(); // 当个数不足时,等待
    } catch (InterruptedException e) {
        e.printStackTrace();
    } catch (BrokenBarrierException e) {
        e.printStackTrace();
    }
    System.out.println("线程1继续向下运行..."+new Date());
}).start();

new Thread(()->{
    System.out.println("线程2开始.."+new Date());
    try {
        Thread.sleep(2000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    try {
        cb.await(); // 2 秒后,线程个数够2,继续运行
    } catch (InterruptedException e) {
        e.printStackTrace();
    } catch (BrokenBarrierException e) {
        e.printStackTrace();
    }
    System.out.println("线程2继续向下运行..."+new Date());
}).start();

与倒计时锁的区别:倒计时锁只能使用一次,倒计时结束这个对象就没用了。
而循环栅栏可以重复利用。

4. 信号量

Semaphore s = new Semaphore(3); // 限制了能同时运行的线程上限
for (int i = 0; i < 10; i++) {
    new Thread(() -> {
        try {
            s.acquire(); // 获得此信号量
            System.out.println("我是线程" + Thread.currentThread().getName());
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            s.release(); // 释放信号量
        }

    }).start();
}

2. 网络模型与协议

enter description here
OSI 七层模式 : 应用层,表示层,会话层,传输层,网络层,链路层,物理层

五层模型: 应用层, 传输层,网络层,链路层,物理层
四层模型 : 应用层, 传输层,网络层,链路层

应用层:http(超文本传输协议) ftp(文件传输协议) stmp (邮件发送协议) pop3(邮件接收协议), ssh ( 安全shell,用于远程登录)

传输层: tcp(安全可靠的协议) udp(不可靠)

网络层:ip

windows下可以使用 ipconfig来查看ip地址
linux 下可以使用 ifconfig来查看ip地址

ip 地址的作用是用来定位到网络上的另一台计算机
port 端口 mysql 3306
oracle 1521
sqlserver 1433
redis 6379
tomcat 8080
apache(http的服务) 80
ftp 21
ssh 22

端口号的作用是用来标记,要访问对方的哪个程序

传输层协议:
tcp协议:
TCP 协议的特点是: TCP 协议是一个有连接、可靠的协议。所谓有连接,指的是在进行 TCP通信之前,两个需要通信的主机之间要首先建立一条数据通道,就好像打电话进行交流之前,首先要让电话接通一样。所谓可靠,指的是 TCP 协议能够保证: 1、发送端发送的数据不会丢失; 2、接收端接受的数据包的顺序,会按照发送端发送的包的顺序接受。也就是说, TCP协议能够保证数据能够完整无误的传输。

udp协议:
与 TCP 协议相比, UDP 是一个无连接,不可靠的协议。 即:数据的发送方只负责将数据发送出去,数据的接受方只负责接受数据。发送方和接收方不会相互确认数据的传输是否成功。
相对于 TCP 而言, UDP 有一个优点:效率较高。因此,当我们在对数据传输的正确率
不太关心,但是对传输效率要求较高的情况下,可以采用 UDP 协议。典型的使用 UDP 协议的是网络语音以及视频聊天应用。

3. java中的网络编程

Socket API 对tcp、udp协议做了封装,能够连接到对方主机,收发数据

tcp的例子

建立连接
服务器端:

public static void main(String[] args) throws IOException {
    // 可以与客户端的socket建立连接  端口号一般使用4位以上的数字
    ServerSocket ss = new ServerSocket(5555);
    System.out.println("ready...等待客户端连接");
    // 端点
    Socket socket = ss.accept();// 等待客户端连接我服务器方法,直到有客户端连接
}

客户端:

public static void main(String[] args) throws IOException {
    // 本机ip地址为 127.0.0.1
    // 它的别名     localhost
    // 端点
    Socket socket =
            new Socket("127.0.0.1", 5555);
}

传输数据
enter description here

4. 设计模式

单例(singleton) 模式:
定义: 在jvm虚拟机中, 某个类只有一个实例,就称之为单例。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值