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.查看帮助 ...
随机推荐
- 如何从零基础学习VR
转载请声明转载地址:http://www.cnblogs.com/Rodolfo/,违者必究. 近期很多搞技术的朋友问我,如何步入VR的圈子?如何从零基础系统性的学习VR技术? 本人将于2017年1月 ...
- 开放封闭原则(Open Closed Principle)
在面向对象的设计中有很多流行的思想,比如说 "所有的成员变量都应该设置为私有(Private)","要避免使用全局变量(Global Variables)",& ...
- jquery实现页面交互的几个小例子
翻看了以前留下的笔记,发现自己竟然做过这么多的页面交互效果,没有使用原生js,全是通过jquery实现的,于是把他们整理下来,附上表现效果图及源代码 1 业务应用:授权商品组和删除商品组 本质:复选框 ...
- CozyRSS开发记录5-订阅列表栏里的项
CozyRSS开发记录5-订阅列表栏里的项 1.订阅列表栏里的项的原型图 这里列表项依然参考傲游的RSS阅读器,以后可能会微调. 2.使用ControlTemplate来定制ListBoxItem 给 ...
- Mac系统 安装SVN
- ios10新特性-UserNotification
引言:iOS的通知分本地通知和远程通知,iOS10之前采用的是UILocationNotification类,远程通知有苹果服务器进行转发,本地通知和远程通知其回调的处理都是通过AppDelegate ...
- /var/run/yum.pid 已被锁定,PID 为 XXXX 的另一个程序正在运行。
安装st-load时, 终端提示 “/var/run/yum.pid 已被锁定,PID 为 13908 的另一个程序正在运行.” 解决方法:直接在终端运行 rm -f /var/run/yum.pid ...
- 简单CSS3动画制作
本贴已重新编辑至http://www.cnblogs.com/fastmover/p/4977358.html 最近需要用到了一些CSS3动画,基本用Animate.css(https://githu ...
- win8 系统安装node环境记录
原先我是用win7环境安装node很方便,到了win8系统突然变了,让我顿时困惑了一段时间,但还是被我找到方式解决了,记录一下解决方案: 首先在网上看了一些资料说win8下安装node环境会出错,但我 ...
- JavaScript函数表达式
函数表达式的基本语法形式 var functionName = function(arguments){ //函数体 } 递归建议 我们通过例子来一步步说明,递归的最佳实现方式.下面是普通递归调用的例 ...