JAVASE02-Unit010: 多线程基础 、 TCP通信
多线程基础 、 TCP通信
* 当一个方法被synchronized修饰后,那么
* 该方法称为同步方法,即:多个线程不能同时
* 进入到方法内部执行。
package day10;
/**
* 当多线程并发操作同一资源时,由于线程切换的不确定
* 性,可能导致执行顺序的混乱,严重时可能导致系统
* 瘫痪。
* @author adminitartor
*
*/
public class SyncDemo1 {
public static void main(String[] args) {
final Table table = new Table();
Thread t1 = new Thread(){
public void run(){
while(true){
int bean = table.getBean();
Thread.yield();//模拟线程切换
System.out.println(getName()+":"+bean);
}
}
};
Thread t2 = new Thread(){
public void run(){
while(true){
int bean = table.getBean();
Thread.yield();//模拟线程切换
System.out.println(getName()+":"+bean);
}
}
}; t1.start();
t2.start();
}
} class Table{
private int beans = 20;
/**
* 当一个方法被synchronized修饰后,那么
* 该方法称为同步方法,即:多个线程不能同时
* 进入到方法内部执行。
* 在方法上使用synchronized那么锁对象为
* 当前方法所属对象,即:this
* @return
*/
public synchronized int getBean(){
if(beans==0){
throw new RuntimeException("没有豆子了!");
}
Thread.yield();//模拟线程切换
return beans--;
}
}
SyncDemo1.java
* 有效的缩小同步范围可以在保证并发安全的前提下
* 提高并发效率。
package day10;
/**
* 有效的缩小同步范围可以在保证并发安全的前提下
* 提高并发效率。
* @author adminitartor
*
*/
public class SyncDemo2 {
public static void main(String[] args) {
final Shop shop = new Shop();
Thread t1 = new Thread(){
public void run(){
shop.buy();
}
};
Thread t2 = new Thread(){
public void run(){
shop.buy();
}
};
t1.start();
t2.start();
}
} class Shop{
public void buy(){
try {
Thread t = Thread.currentThread();
System.out.println(t.getName()+":正在挑选衣服...");
Thread.sleep(5000);
/*
* 多个线程要保证同步执行代码的前提是
* 这里看到的"同步监视器"即:上锁的对象
* 是同一个。
*/
synchronized(this){
System.out.println(t.getName()+":正在试衣服...");
Thread.sleep(5000);
}
System.out.println(t.getName()+":结账离开");
} catch (Exception e) {
e.printStackTrace();
} }
}
SyncDemo2.java
* 每个类在被JVM加载时,JVM都会创建一个且只创建
* 一个Class类型的实例来表示它。所以,每个类在
* JVM内部都有唯一的一个Class类型的实例对应,而
* 静态方法就是将该Class的实例上锁的。
package day10;
/**
* 静态方法若使用synchronized修饰后,那么该方法
* 一定具有同步效果。
* 静态方法的同步监视器对象为当前类的类对象。
* 类对象:Class类型的实例。
* 每个类在被JVM加载时,JVM都会创建一个且只创建
* 一个Class类型的实例来表示它。所以,每个类在
* JVM内部都有唯一的一个Class类型的实例对应,而
* 静态方法就是将该Class的实例上锁的。
* @author adminitartor
*
*/
public class SyncDemo3 {
public static void main(String[] args) {
Thread t1 = new Thread(){
public void run(){
Foo.dosome();
}
};
Thread t2 = new Thread(){
public void run(){
Foo.dosome();
}
};
t1.start();
t2.start();
}
} class Foo{
public synchronized static void dosome(){
try {
Thread t = Thread.currentThread();
System.out.println(t.getName()+":正在运行dosome方法...");
Thread.sleep(5000);
System.out.println(t.getName()+":运行dosome方法完毕!");
} catch (Exception e) {
e.printStackTrace();
}
}
}
SyncDemo3.java
* 互斥锁
package day10;
/**
* 互斥锁
* 当使用Synchronized修饰多段不同代码,但是同步
* 监视器对象是同一个的时候,那么这些代码间就具有
* 了互斥性,同一时间不能同时执行这些代码。
* @author adminitartor
*
*/
public class SyncDemo4 {
public static void main(String[] args) {
final Boo boo = new Boo();
Thread t1 = new Thread(){
public void run(){
boo.methodA();
}
};
Thread t2 = new Thread(){
public void run(){
boo.methodB();
}
};
t1.start();
t2.start();
}
} class Boo{
public void methodA(){
synchronized(this){
try {
Thread t = Thread.currentThread();
System.out.println(
t.getName()+":正在执行A方法");
Thread.sleep(5000);
System.out.println(
t.getName()+":执行A方法完毕");
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void methodB(){
synchronized(this){
try {
Thread t = Thread.currentThread();
System.out.println(t.getName()+":正在执行B方法");
Thread.sleep(5000);
System.out.println(t.getName()+":执行B方法完毕");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
SyncDemo4.java
* 死锁
package day10;
/**
* 死锁
* 双方都持有自己的锁,但都要求对方先释放锁时
* 出现死锁现象。
* @author adminitartor
*
*/
public class SyncDemo5 {
public static void main(String[] args) {
final Coo coo = new Coo();
Thread t1 = new Thread(){
public void run(){
coo.methodA();
}
};
Thread t2 = new Thread(){
public void run(){
coo.methodB();
}
};
t1.start();
t2.start();
}
} class Coo{
private Object lockA = new Object();
private Object lockB = new Object(); public void methodA(){
try {
Thread t = Thread.currentThread();
synchronized (lockA) {
System.out.println(t.getName()+"正在运行A方法");
Thread.sleep(5000);
methodB();
System.out.println(t.getName()+"运行A方法完毕");
} } catch (Exception e) {
}
}
public void methodB(){
try {
Thread t = Thread.currentThread();
synchronized (lockB) {
System.out.println(t.getName()+"正在运行B方法");
Thread.sleep(5000);
methodA();
System.out.println(t.getName()+"运行B方法完毕");
} } catch (Exception e) {
}
}
}
SyncDemo5.java
* 使用Collections的静态方法可以将现有的集合
* 或Map转换为线程安全的
package day10; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set; /**
* 使用Collections的静态方法可以将现有的集合
* 或Map转换为线程安全的
* @author adminitartor
*
*/
public class Sync_API {
public static void main(String[] args) {
/*
* 线程安全的集合自身的add,remove等方法
* 都是同步的,并且之间也有互斥。
* 但是并不与迭代器遍历互斥。所以若并发
* 同时遍历和增删元素,迭代器依然会抛出
* 异常。
* 所以,迭代器与集合元素操作间要自行维护
* 互斥关系。
*
* ArrarList,LinkedList都不是线程安全的
*/
List<String> list
= new ArrayList<String>();
list.add("one");
list.add("two");
list.add("three");
list.add("four");
System.out.println(list);
//将给定的集合转换为一个线程安全的集合
list = Collections.synchronizedList(list); System.out.println(list); Set<String> set
= new HashSet<String>(list);
set = Collections.synchronizedSet(set);
System.out.println(set); Map<String,Integer> map
= new HashMap<String,Integer>();
map.put("语文", 100);
map.put("数学", 99);
map.put("英语", 98); map = Collections.synchronizedMap(map);
System.out.println(map);
}
}
Sync_API.java
* 线程池
package day10; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; /**
* 线程池
* 线程池有两个主要作用:
* 1:控制线程数量
* 2:重用线程
* @author adminitartor
*
*/
public class ThreadPool_Demo {
public static void main(String[] args) {
ExecutorService threadPool
= Executors.newFixedThreadPool(2); for(int i=0;i<5;i++){
Runnable runn = new Runnable(){
public void run(){
Thread t = Thread.currentThread();
System.out.println(t.getName()+":正在运行任务...");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(t.getName()+":运行任务完毕!");
}
};
threadPool.execute(runn);
} //结束线程池
threadPool.shutdown();
System.out.println("线程池结束了!");
}
}
ThreadPool_Demo.java
案例一:
* 封装了TCP通讯的Socket
* 使用它可以与服务端建立连接,并进行通讯
package chat; import java.net.Socket; /**
* 聊天室客户端
* @author adminitartor
*
*/
public class Client {
/*
* 封装了TCP通讯的Socket
* 使用它可以与服务端建立连接,并进行通讯
*
*/
private Socket socket;
/**
* 构造方法,用来初始化客户端
*/
public Client() throws Exception{
/*
* 实例化Socket的过程就是连接服务端的
* 过程。若连接失败,这里会抛出异常
*
* 构造方法的两个参数:
* 1:服务端计算机的IP地址
* 2:服务端应用程序的端口
*/
socket = new Socket(
"localhost",8088
);
}
/**
* 客户端开始工作的方法
*/
public void start(){ } public static void main(String[] args) {
try {
Client client = new Client();
client.start();
} catch (Exception e) {
e.printStackTrace();
System.out.println("客户端运行失败!");
}
}
}
Client.java
* 聊天室服务端
package chat; import java.net.ServerSocket;
import java.net.Socket; /**
* 聊天室服务端
* @author adminitartor
*
*/
public class Server {
/*
* 运行在服务端的ServerSocket,主要作用:
* 1:向操作系统申请服务端口,客户端就是通过
* 这个端口与服务端程序建立连接的
* 2:监听服务端口,一旦客户端连接了,就会创建
* 一个Socket以便与该客户端交互
*/
private ServerSocket server; /**
* 构造方法,用来初始化服务端
* @throws Exception
*/
public Server() throws Exception{
/*
* 初始化,并申请服务端口,若该端口被
* 其他应用程序占用,这里会抛出异常
*/
server = new ServerSocket(8088);
} public void start(){
try {
/*
* ServerSocket提供方法:
* Socket accept()
* 该方法是一个阻塞方法,直到一个客户端
* 通过申请的端口连接上,这里才会返回
* 返回的是一个Socket实例,通过该实例
* 即可与刚连接的客户端交互。
*/
System.out.println("等待客户端连接...");
Socket socket = server.accept();
System.out.println("一个客户端连接了!"); } catch (Exception e) {
e.printStackTrace();
}
} public static void main(String[] args) {
try {
Server server = new Server();
server.start();
} catch (Exception e) {
e.printStackTrace();
System.out.println("服务端运行失败!");
}
}
}
Server.java
JAVASE02-Unit010: 多线程基础 、 TCP通信的更多相关文章
- 性能测试基础 ---TCP通信过程的状态码与过程,以及出现错误码的分析(TIME_WAIT,CLOSE_WAIT)
TCP通信过程 如下图所示,TCP通信过程包括三个步骤:建立TCP连接通道(三次握手).数据传输.断开TCP连接通道(四次挥手). 这里进一步探究TCP三路握手和四次挥手过程中的状态变迁以及数据传输过 ...
- 多线程基础(五)NSThread线程通信
5.多线程基础 线程间通信 什么叫线程间通信 在一个进程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信 线程间通信的体现 1个线程传递数据给另一个线程 在1个线程中执行完特定任务后, ...
- UE4 Sockets多线程TCP通信
转自:https://blog.csdn.net/zilisen/article/details/75007447 一.简介 UE4引擎是提供了Sockets模块和Networking模块的,博主在研 ...
- Java基础教程:多线程基础(2)——线程间的通信
Java基础教程:多线程基础(2)——线程间的通信 使线程间进行通信后,系统之间的交互性会更强大,在大大提高CPU利用率的同时还会使程序员对各线程任务在处理的过程中进行有效的把控与监督. 线程间的通信 ...
- TCP通信 - 服务器开启多线程与read()导致服务器阻塞问题
TCP通信的文件上传案例 本地流:客户端和服务器和本地硬盘进行读写,需要使用自己创建的字节流 网络流:客户端和服务器之间读写,必须使用Socket中提供的字节流对象 客户端工作:读取本地文件,上传到服 ...
- TCP通信---文件上传案例、多线程文件上传
目前大多数服务器都会提供文件上传的功能,由于文件上传需要数据的安全性和完整性,很明显需要使用TCP协议来实现. TCP通信需要创建一个服务器端程序和一个客户端程序,实现客户端向服务器端上传文件 代码实 ...
- 【Java TCP/IP Socket】深入剖析socket——TCP通信中由于底层队列填满而造成的死锁问题(含代码)
基础准备 首先需要明白数据传输的底层实现机制,在http://blog.csdn.net/ns_code/article/details/15813809这篇博客中有详细的介绍,在上面的博客中,我们提 ...
- 多线程实现tcp聊天服务器
多线程tcp server & client tcp服务端(多线程): from socket import * from threading import Thread def clien ...
- Java进阶:基于TCP通信的网络实时聊天室
目录 开门见山 一.数据结构Map 二.保证线程安全 三.群聊核心方法 四.聊天室具体设计 0.用户登录服务器 1.查看当前上线用户 2.群聊 3.私信 4.退出当前聊天状态 5.离线 6.查看帮助 ...
随机推荐
- C++ 基础知识复习(一)
数据类型,常量与变量部分:(发现有些点竟然这么多年第一次发现) C++基本数据类型有哪些: 答:整型,浮点型,void型. 注:其他各种数据类型均是这三种类型的扩充,另外void类型在实际程序中经常用 ...
- C# 显示问题
- 话说IOC(DI)
什么是IOC(DI) 书上的东东,因为说的太严谨,所以不太容易懂,其实也没那么复杂. 举几个例子: 1.文明点的:中午太热,不想出去吃饭,所以希望同事能帮忙带饭,现在有了点外卖平台,我们就可以直接在网 ...
- Monitoring Processes with Supervisord
If you're interested in more of this type of content, check out the Servers for Hackers eBook! As so ...
- HYSBZ 2002 分块
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2002 题意:中文题面 思路:考虑分块,每个位置维护一个跳出该块需要的步数cnt[],和跳出 ...
- jq switch case
switch (cnt) { case ("string1"): ... ...
- C# 的EF框架怎么连接Oracle数据库
安装odp.net ODP.NET你不需要安装Oracle,不需要配置oracle.key文件,不需要配置TnsNames.Ora文件 不需要配置环境变量:完全的傻瓜式的在没有安装oracle数据库或 ...
- CodeForces 520B Two Buttons(用BFS)
Two Buttons time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...
- 【oracle】oracle表结构导出到Word
因为需要写数据库文档,所以需要把数据库里边的表结构在word中用表格列出来,之前一直用powerdesigner,感觉有些麻烦,后来在网上找到了一段sql语句,经测试完全符合我的需求,不敢独享,语句如 ...
- Unity Lightmap动态加载研究
什么情况下需要Lightmap? 移动平台上目前暂时还不能开实时光影效果,会卡成幻灯片.所以就需要将光影烘焙到贴图上. 什么情况下需要动态加载Lightmap? 1.当项目抛弃了Unity的多场景模式 ...