多线程基础 、 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通信的更多相关文章

  1. 性能测试基础 ---TCP通信过程的状态码与过程,以及出现错误码的分析(TIME_WAIT,CLOSE_WAIT)

    TCP通信过程 如下图所示,TCP通信过程包括三个步骤:建立TCP连接通道(三次握手).数据传输.断开TCP连接通道(四次挥手). 这里进一步探究TCP三路握手和四次挥手过程中的状态变迁以及数据传输过 ...

  2. 多线程基础(五)NSThread线程通信

    5.多线程基础 线程间通信   什么叫线程间通信 在一个进程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信   线程间通信的体现 1个线程传递数据给另一个线程 在1个线程中执行完特定任务后, ...

  3. UE4 Sockets多线程TCP通信

    转自:https://blog.csdn.net/zilisen/article/details/75007447 一.简介 UE4引擎是提供了Sockets模块和Networking模块的,博主在研 ...

  4. Java基础教程:多线程基础(2)——线程间的通信

    Java基础教程:多线程基础(2)——线程间的通信 使线程间进行通信后,系统之间的交互性会更强大,在大大提高CPU利用率的同时还会使程序员对各线程任务在处理的过程中进行有效的把控与监督. 线程间的通信 ...

  5. TCP通信 - 服务器开启多线程与read()导致服务器阻塞问题

    TCP通信的文件上传案例 本地流:客户端和服务器和本地硬盘进行读写,需要使用自己创建的字节流 网络流:客户端和服务器之间读写,必须使用Socket中提供的字节流对象 客户端工作:读取本地文件,上传到服 ...

  6. TCP通信---文件上传案例、多线程文件上传

    目前大多数服务器都会提供文件上传的功能,由于文件上传需要数据的安全性和完整性,很明显需要使用TCP协议来实现. TCP通信需要创建一个服务器端程序和一个客户端程序,实现客户端向服务器端上传文件 代码实 ...

  7. 【Java TCP/IP Socket】深入剖析socket——TCP通信中由于底层队列填满而造成的死锁问题(含代码)

    基础准备 首先需要明白数据传输的底层实现机制,在http://blog.csdn.net/ns_code/article/details/15813809这篇博客中有详细的介绍,在上面的博客中,我们提 ...

  8. 多线程实现tcp聊天服务器

    多线程tcp  server & client tcp服务端(多线程): from socket import * from threading import Thread def clien ...

  9. Java进阶:基于TCP通信的网络实时聊天室

    目录 开门见山 一.数据结构Map 二.保证线程安全 三.群聊核心方法 四.聊天室具体设计 0.用户登录服务器 1.查看当前上线用户 2.群聊 3.私信 4.退出当前聊天状态 5.离线 6.查看帮助 ...

随机推荐

  1. C# 如何用多个字符串来切分字符串并去除空格

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.D ...

  2. Pyqt SpVoice朗读功能

    用Pyqt 做一个读取系统剪贴板内容,然后通过语音合成(TTS)朗读出剪贴板的内容 知识要点 SpVoice SpVoice类是支持语音合成(TTS)的核心类.通过SpVoice对象调用TTS引擎,从 ...

  3. python多线程编程

    Python多线程编程中常用方法: 1.join()方法:如果一个线程或者在函数执行的过程中调用另一个线程,并且希望待其完成操作后才能执行,那么在调用线程的时就可以使用被调线程的join方法join( ...

  4. partial class的使用范围

    Partial Class,部分类 或者分布类.顾名思义,就是将一个类分成多个部分.比如说:一个类中有3个方法,在VS 2005将该类中3个方法分别存放在3个不同的.cs文件中. 这样做的好处: 1. ...

  5. mysql常见错误及解决方案

    mysql error 2005 - Unknown MySQL server host 'localhost'(0) 此错误一般为地址信息错误,注意是否有空格. 在连接本地数据库时,最好使用127. ...

  6. MIT 6.828 JOS学习笔记8. Exercise 1.4

    Lab 1 Exercise 4 阅读关于C语言的指针部分的知识.最好的参考书自然是"The C Programming Language". 阅读5.1到5.5节.然后下载poi ...

  7. Delphi基本类型--枚举 子界 集合 数组

    [plain] view plain copy <strong>根据枚举定义集合 </strong> TMyColor = (mcBlue, mcRed); TMyColorS ...

  8. Prototypes in Javascript 收集.__proto__

    It’s important to understand that a function’s prototype property has nothing to do with it’s actual ...

  9. How To Handle a Loss of Confidence in Yourself

    Do you feel like you've lost confidence in yourself? Have you had strong self doubts? Perhaps you we ...

  10. CF #375 (Div. 2) D. bfs

    1.CF #375 (Div. 2)  D. Lakes in Berland 2.总结:麻烦的bfs,但其实很水.. 3.题意:n*m的陆地与水泽,水泽在边界表示连通海洋.最后要剩k个湖,总要填掉多 ...