网络编程笔记

网络编程

多线程的作业

Ticket.java

package com.qfedu.homework;

public class Ticket implements Runnable{
	
	private int ticket = 100;

	@Override
	public void run() {
		try {
			while(true) {
				//Thread.sleep(100);
				sellTicket();
				
				if(ticket <= 0) {
					break;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 卖票的方法
	 */
	public synchronized void sellTicket() {
		if(ticket > 0) {
			System.out.println(Thread.currentThread().getName() + "正在售出第" + ticket-- + "张票");
		}
	}
}

​ TicketTest.java

package com.qfedu.homework;

public class TicketTest {

	public static void main(String[] args) {
		Ticket ticket = new Ticket();
		
		Thread t1 = new Thread(ticket, "12306");
		Thread t2 = new Thread(ticket, "火车站");
		Thread t3 = new Thread(ticket, "代售点");
		Thread t4 = new Thread(ticket, "黄牛");
		
		t1.start();
		t2.start();
		t3.start();
		t4.start();
	}
}

命名规范

  1. 驼峰命名法则

    1. 一般用于变量,方法命名
      2. 比如setName, main, getUsername,money
  2. Pascal命名法

    1. 一般用于类名,接口名,枚举类型名,注解类型名
      2. HelloWorld, Days02Net, Ticket, TicketTest
  3. 匈牙利命名法

    1. 一般用于控件命名,给给定变量前或者后,添加额外的前缀或者后缀
      2. txtUsername, lblAge, btnSubmit
  4. 全大写

    1. 一般用于常量命名
      2. MAX_PRIORITY, MALE, FEMALE, MAX_VALUE
  5. 全小写

    1. 一般用于包名
      2. com.baidu, com.qfedu

    小贴士:

    ​ 4代表four,进一步代表for, log4j

    ​ 2代表two,进一步代表to, rmb2Usd

    ​ 编码规范,自行下载一个大型公司的编码规范 阿里规范

锁机制

1.	**synchronized** 关键字
         	1.	同步代码块,锁为任意的非空对象,注意不能放基本类型的数据
                   	2.	同步方法,锁为this
                   	3.	静态同步方法,锁为类.class类对象
2.	ReentrantLock API
   1. lock
   2. unlock

PayMoney.java

package com.qfedu.lock;

import java.util.concurrent.locks.ReentrantLock;

public class PayMoney implements Runnable {

	int money = 5000 * 3;
	static int money2 = 5000 * 3;

	ReentrantLock lock = new ReentrantLock();

	@Override
	public void run() {
		for (int i = 0; i < 10; i++) {
			// pay();
			// pay02();
			// pay03();
			// pay04();
			 pay05();
		}
	}

	// 会出现临界资源问题的代码
	public void pay() {
		System.out.println(Thread.currentThread().getName() + "目前余额" + money);
		money -= 500;
		System.out.println(Thread.currentThread().getName() + "付款完余额" + money);

		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	// 同步对象锁
	public void pay02() {
		synchronized ("") {		//同步代码块
			System.out.println(Thread.currentThread().getName() + "目前余额" + money);
			money -= 500;
			System.out.println(Thread.currentThread().getName() + "付款完余额" + money);

			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	// 同步方法锁
	public synchronized void pay03() {
		System.out.println(Thread.currentThread().getName() + "目前余额" + money);
		money -= 500;
		System.out.println(Thread.currentThread().getName() + "付款完余额" + money);

		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 静态同步方法
	 */
	public synchronized static void pay04() {
		System.out.println(Thread.currentThread().getName() + "目前余额" + money2);
		if (money2 >= 500)
			money2 -= 500;
		System.out.println(Thread.currentThread().getName() + "付款完余额" + money2);

		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 使用ReentrantLock类来实现同步的锁的功能
	 */
	public void pay05() {
		lock.lock(); // 上锁代码,之后的所有代码将以“独占”的方式执行,知道unlock()出现

		System.out.println(Thread.currentThread().getName() + "目前余额" + money2);
		if (money >= 500)
			money2 -= 500;
		System.out.println(Thread.currentThread().getName() + "付款完余额" + money2);

		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}finally {
			lock.unlock(); // 解锁,之前锁定的代码就可以开放被下一个线程对象来访问执行
		}
	}
}

​ PayMoneyTest.java

package com.qfedu.lock;

public class PayMoneyTest {

	public static void main(String[] args) {
		PayMoney pm = new PayMoney();
		
		Thread t1 = new Thread(pm, "迪丽热巴");
		Thread t2 = new Thread(pm, "马尔扎哈");
		Thread t3 = new Thread(pm, "全智贤");
		
		t1.start();
		t2.start();
		t3.start();
	}

}

生产者消费者问题

BreadFactory.java

package com.qfedu.procon;

public class BreadFactory {

	private final static int MAX_NUM = 5000;		//	仓库的最大容量
	
	private int currentNum;							//	当前仓库库存
	
	public void setCurrentNum(int currentNum) {
		this.currentNum = currentNum;
	}
	
	/**
	 * 
	 * 生产者的生产方法
	 * 
	 * @param num 生产者要生产的数量
	 */
	public synchronized void produce(int num) {
		System.out.println("当前面包库存有" + currentNum + ",尝试生产面包数为" + num);
		
		try {
			Thread.sleep(100);
			while(true) {
				if(num + currentNum > MAX_NUM) {		//要生产的面包数加上当前面包数大雨库存
					System.out.println("容量不足,暂停生产...");
					wait();
				}else {
					break;
				}
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		currentNum += num;		//	当前库存更新
		System.out.println("成功生产了" + num + "箱面包,当前库存为" + currentNum);
		
		notify();			//	唤醒线程队列中的任意一个随机线程来执行
	}
	
	/**
	 * 
	 * 消费者的消费方法
	 * 
	 * @param num 消费者要消费的数量
	 */
	public synchronized void consume(int num) {
		System.out.println("当前库存为" + currentNum + ",尝试要消费面包数为" + num);
		
		try {
			Thread.sleep(100);
			while(true) {
				if(num > currentNum) {
					System.out.println("库存不足,无法消费...");
					wait();
				}else {
					break;
				}
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		currentNum -= num;
		System.out.println("成功消费了" + num + "箱面包,当前库存为" + currentNum);
		
		notify();
	}
}

Producer.java

package com.qfedu.procon;

public class Producer implements Runnable {
	
	private BreadFactory bf;
	private int num;
	
	/**
	 * 在指定工厂中消费指定数量的面包
	 * @param bf	要生产的工厂对象
	 * @param num	要生产的面包数
	 */
	public Producer(BreadFactory bf, int num) {
		this.bf = bf;
		this.num = num;
	}

	@Override
	public void run() {
		//	在bf工厂中生产num箱面包
		bf.produce(num);
	}

}

Consumer.java

package com.qfedu.procon;

public class Consumer implements Runnable {
	
	private BreadFactory bf;
	private int num;
	
	/**
	 * 在指定工厂中消费指定数量的面包
	 * @param bf	要消费的工厂对象
	 * @param num	要消费的面包数
	 */
	public Consumer(BreadFactory bf, int num) {
		this.bf = bf;
		this.num = num;
	}

	@Override
	public void run() {
		//	在bf工厂中消费num箱面包
		bf.consume(num);
	}

}

TestBreakFactory.java

package com.qfedu.procon;

public class TestBreakFactory {

	public static void main(String[] args) {
		BreadFactory bf = new BreadFactory();
		
		bf.setCurrentNum(100);
		
		//	在指定的面包工厂中创建4个生产者对象,并指定要生产的数量
		Producer p1 = new Producer(bf, 500);
		Producer p2 = new Producer(bf, 500);
		Producer p3 = new Producer(bf, 800);
		Producer p4 = new Producer(bf, 1200);

		//	在指定的面包工厂中创建4个消费者对象,并指定要消费的数量
		Consumer c1 = new Consumer(bf, 600);
		Consumer c2 = new Consumer(bf, 400);
		Consumer c3 = new Consumer(bf, 700);
		Consumer c4 = new Consumer(bf, 400);
		
		Thread t1 = new Thread(p1);
		Thread t2 = new Thread(p2);
		Thread t3 = new Thread(p3);
		Thread t4 = new Thread(p4);
		
		Thread t5 = new Thread(c1);
		Thread t6 = new Thread(c2);
		Thread t7 = new Thread(c3);
		Thread t8 = new Thread(c4);
		
		t1.start();
		t2.start();
		t3.start();
		t4.start();
		t5.start();
		t6.start();
		t7.start();
		t8.start();
	}
}

sleep与wait对比

共同点:都会抛出InterruptedException异常

sleep

1.	休息指定时间,自动处于可运行状态

2.	不释放锁
3.	Thread类的静态方法,只能通过Thread类或者对象来引入
4.	Thread 类中有两个重载的方法

wait

1.	等待,需要被唤醒(notify/notifyAll方法)

2.	会释放锁
3.	Object的方法,哪里都可以使用
4.	Object类中有三个重载的方法

网络编程

计算机网络

网络七层架构

TCP/UDP

2.11作业
  1. 完成生产者消费者代码的编写(三遍)
  2. 翻阅jdk文档熟悉Object类,Thread类,ReentrantLock类中是所有内容
  3. 预习网络编程内容
  4. 同步代码块,同步方法
  5. Lock
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值