线程,5TCP通信程序练习

140 阅读4分钟

线程同步2.1卖票【应用】

案例需求

某电影院目前正在上映国产大片,共有100张票,而它有3个窗口卖票,请设计一个程序模拟该电影院卖票

实现步骤


定义一个类SellTicket实现Runnable接口,里面定义一个成员变量:private int tickets = 100;

在SellTicket类中重写run()方法实现卖票,代码步骤如下

判断票数大于0,就卖票,并告知是哪个窗口卖的

卖了票之后,总票数要减1

票没有了,也可能有人来问,所以这里用死循环让卖票的动作一直执行

定义一个测试类SellTicketDemo,里面有main方法,代码步骤如下

创建SellTicket类的对象

创建三个Thread类的对象,把SellTicket对象作为构造方法的参数,并给出对应的窗口名称

[Java] 纯文本查看 复制代码

?

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

public class SellTicket implements Runnable {

private int tickets = 100;

//在SellTicket类中重写run()方法实现卖票,代码步骤如下

@Override

public void run() {

while (true) {

if (tickets > 0) {

System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");

tickets--;

}

}

}

}

public class SellTicketDemo {

public static void main(String[] args) {

//创建SellTicket类的对象

SellTicket st = new SellTicket(); //创建三个Thread类的对象,把SellTicket对象作为构造方法的参数,并给出对应的窗口名称

Thread t1 = new Thread(st,"窗口1");

Thread t2 = new Thread(st,"窗口2");

Thread t3 = new Thread(st,"窗口3"); //启动线程

t1.start();

t2.start();

t3.start();

}

}

3同步代码块解决数据安全问题【应用】
安全问题出现的条件


是多线程环境

有共享数据

有多条语句操作共享数据

如何解决多线程安全问题呢?


基本思想:让程序没有安全问题的环境

怎么实现呢?


把多条语句操作共享数据的代码给锁起来,让任意时刻只能有一个线程执行即可

Java提供了同步代码块的方式来解决

同步代码块格式:

synchronized(任意对象) {
多条语句操作共享数据的代码
}
synchronized(任意对象):就相当于给代码加锁了,任意对象就可以看成是一把锁

同步的好处和弊端


好处:解决了多线程的数据安全问题

弊端:当线程很多时,因为每个线程都会去判断同步上的锁,这是很耗费资源的,无形中会降低程序的运行效率


[AppleScript] 纯文本查看 复制代码

?

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

代码演示public class SellTicket implements Runnable {

private int tickets = 100;

private Object obj = new Object(); @Override

public void run() {

while (true) {

//tickets = 100;

//t1,t2,t3

//假设t1抢到了CPU的执行权

//假设t2抢到了CPU的执行权

synchronized (obj) {

//t1进来后,就会把这段代码给锁起来

if (tickets > 0) {

try {

Thread.sleep(100);

//t1休息100毫秒

} catch (InterruptedException e) {

e.printStackTrace();

}

//窗口1正在出售第100张票

System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");

tickets--; //tickets = 99;

}

}

//t1出来了,这段代码的锁就被释放了

}

}

}public class SellTicketDemo {

public static void main(String[] args) {

SellTicket st = new SellTicket(); Thread t1 = new Thread(st, "窗口1");

Thread t2 = new Thread(st, "窗口2");

Thread t3 = new Thread(st, "窗口3"); t1.start();

t2.start();

t3.start();

}

}

5TCP通信程序练习【应用】
案例需求

客户端:数据来自于键盘录入,直到输入的数据是886,发送数据结束

服务端:接受到的数据写入文本文件中

案例分析


客户端创建对象,使用键盘录入循环接受数据,接受一行发送一行,直到键盘录入886为止

服务端创建对象,创建输出流对象指向文件,每接受一行数据后使用输出流输出到文件中,直到接受到null为止

代码实现

[AppleScript] 纯文本查看 复制代码

?

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

ublic class ClientDemo {

public static void main(String[] args) throws IOException {

//创建客户端Socket对象

Socket s = new Socket("192.168.1.66",10000);

//数据来自于键盘录入,直到输入的数据是886,发送数据结束

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

//封装输出流对象

BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));

String line;

while ((line=br.readLine())!=null) {

if("886".equals(line)) {

break;

}

bw.write(line);

bw.newLine();

bw.flush();

}

//释放资源

s.close();

}

}

public class ServerDemo {

public static void main(String[] args) throws IOException {

//创建服务器Socket对象

ServerSocket ss = new ServerSocket(10000);

//监听客户端连接,返回一个对应的Socket对象

Socket s = ss.accept();

//接收数据

BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));

//把数据写入文本文件

BufferedWriter bw = new BufferedWriter(new FileWriter("myNet\s.txt"));

String line;

while ((line=br.readLine())!=null) {

bw.write(line);

bw.newLine();

bw.flush();

}

//释放资源

bw.close();

ss.close();

}

}