线程组
线程组:将属于同一类的线程划分到同一组中,可以直接对线程组进行设置。
ThreadGroup
构造方法:
ThreadGroup(String name) 构造一个新的线程组。
class MyThread1 extends Thread{
public MyThread1() {
}
public MyThread1(ThreadGroup group, String name) {
//父类的构造方法Thread(ThreadGroup group, String name)
super(group, name);
}
@Override
public void run() {
System.out.println("这是帅哥线程");
}
}
//创建线程组,组名自定义
ThreadGroup tg1 = new ThreadGroup("帅哥组");
ThreadGroup tg2 = new ThreadGroup("美女组");
//创建多个线程对象,分配到线程组中
// MyThread1 t1 = new MyThread1();
// t1.setName("李刚");
//Thread(ThreadGroup group, String name)
//分配一个新的 Thread对象。
MyThread1 t1 = new MyThread1(tg1, "李刚");
MyThread1 t2 = new MyThread1(tg1, "钱志强");
MyThread1 t3 = new MyThread1(tg2, "李世博");
MyThread1 t4 = new MyThread1(tg2, "杨珊珊");
线程池:ThreadPool
Executors:
static ExecutorService newCachedThreadPool() 创建一个根据需要创建新线程的线程池,但在可用时将重新使用以前构造的线程。
static ExecutorService newFixedThreadPool(int nThreads) 创建一个线程池,该线程池重用固定数量的从共享无界队列中运行的线程。
static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) 创建一个线程池,可以调度命令在给定的延迟之后运行,或定期执行。
public class ThreadPoolDemo1 {
public static void main(String[] args) {
//创建一个固定大小的线程池
ExecutorService pool = Executors.newFixedThreadPool(2);
//Future<?> submit(Runnable task);
pool.submit(new MyRunnable());
pool.submit(new MyRunnable());
//可用时将重新使用以前构造的线程。
pool.submit(new MyRunnable());
//创建了一个匿名内部类Callable<Object>的实例,并将其提交给ExecutorService对象pool。这个匿名内部类实现了Callable接口,并覆盖了call方法
pool.submit(new Callable<Object>() {
@Override
public Object call() throws Exception {
for (int i = 1; i <= 100; i++) {
System.out.println(Thread.currentThread().getName() + " - " + i);
}
return null;
}
虽然有四个线程但是线程池里实际只有2个线程 可用时将重新使用以前构造的线程
定时器
/*
定时器:Timer
定时任务:TimerTask
*/
public class TimerDemo1 {
public static void main(String[] args) {
//创建一个定时器
Timer timer = new Timer();
//public void schedule(TimerTask task, long delay) 延迟多少毫秒后执行定义任务
timer.schedule(new MyTask(timer), 5000);
//public void schedule(TimerTask task,long delay,long period) 延迟delay毫秒后执行定义任务,后续每间隔period毫米执行一次
timer.schedule(new MyTask(timer), 5000,2000);
}
}
class MyTask extends TimerTask{
Timer timer;
public MyTask(Timer timer) {
this.timer = timer;
}
@Override
public void run() {
System.out.println("砰!爆炸了.....");
//是一个方法调用,通常用于取消一个 Timer 对象中已经安排但尚未执行的任务
// timer.cancel();
}
}
单例模式
/*
单例模式:在整个java程序运行期间,内存中某一个对象有且仅只能有一个。笔试
1. 饿汉式 工作开发中
2. 懒汉式 面试的时候说,可能会涉及线程安全的问题。
/*
懒汉式 需要再创建
*/
// t1, t2, t3
public class Student2 {
private static Student2 student2;
private Student2(){}
public synchronized static Student2 getStudent2(){
if(student2==null){
// t1 , t2, t3
student2 = new Student2();
}
return student2;
}
}
/*
饿汉式 在成员变量中创建好
*/
public class Student1 {
private static Student1 student1 = new Student1();
private Student1(){}
public static Student1 getStudent1(){
return student1;
}
}
*/
/*
设计模式:
创建型模式
简单工厂模式
public class AnimalFactory {
private AnimalFactory() {
}
public static Animal createAnimal(String name){
if("dog".equals(name)){
return new Dog();
}else if("cat".equals(name)){
return new Cat();
}else {
System.out.println("没有该动物");
return null;
}
}
}
工厂方法模式
public class DogFactory extends AnimalFactory{
@Override
public Animal createAnimal() {
return new Dog();
}
}
单例模式
行为型模式
结构型模式
*/
InetAddress
/*
InetAddress: java提供的类,用于表示ip地址
*/
public class InetAddressDemo1 {
public static void main(String[] args) throws Exception {
// static InetAddress getLocalHost()
//返回本地主机的地址。
InetAddress ip1 = InetAddress.getLocalHost();
System.out.println(ip1);
// String getHostName()
//获取此IP地址的主机名。
String hostName = ip1.getHostName();
//String getHostName()
//获取此IP地址的主机名。
String ip = ip1.getHostAddress();
System.out.println("主机名: "+hostName+", ip地址:"+ip);
}
}
UDP
udp接收端
/*
1:建立udp的socket服务.
2:通过receive方法接收数据
3:将收到的数据存储到数据包对象中
4:通过数据包对象的功能来完成对接收到数据进行解析.
5:可以对资源进行关闭
*/
public class ReceiveDemo1 {
public static void main(String[] args) throws Exception{
// 1:建立udp的socket服务
DatagramSocket socket = new DatagramSocket(10086);
// 2:通过receive方法接收数据
//public synchronized void receive(DatagramPacket p)
byte[] bytes = new byte[1024];
DatagramPacket packet = new DatagramPacket(bytes, bytes.length);
socket.receive(packet);
//4:通过数据包对象的功能来完成对接收到数据进行解析.
byte[] data = packet.getData();
int length = packet.getLength();
String info = new String(data, 0, length);
System.out.println("发送段发来一条消息:"+info);
// 5:可以对资源进行关闭
socket.close();
}
}
udp发送端
/*
1:建立udp的socket服务
2:将要发送的数据封装成数据包
3:通过udp的socket服务,将数据包发送出
4:关闭资源
*/
public class SendDemo1 {
public static void main(String[] args) throws Exception{
// 1:建立udp的socket服务
// DatagramSocket
//DatagramSocket()
//构造数据报套接字并将其绑定到本地主机上的任何可用端口。
DatagramSocket socket = new DatagramSocket();
// 2:将要发送的数据封装成数据包 DatagramPacket
//DatagramPacket(byte[] buf, int length, InetAddress address, int port)
//构造用于发送长度的分组的数据报包 length指定主机上到指定的端口号。
byte[] bytes = "李刚来了...".getBytes();
int length = bytes.length;
InetAddress address = InetAddress.getByName("192.168.22.15");
DatagramPacket packet = new DatagramPacket(bytes, length, address, 10086);
// 3:通过udp的socket服务,将数据包发送出
//public void send(DatagramPacket p)
socket.send(packet);
// 4:关闭资源
socket.close();
}
}
TCP
/*
1:建立服务器端的socket服务,需要一个端口
2:服务端没有直接流的操作,而是通过accept方法获取客户端对象,在通过获取到的客户端对象的流和客户端进行通信
3:通过客户端的获取流对象的方法,读取数据或者写入数据
4:如果服务完成,需要关闭客户端,然后关闭服务器,但是,一般会关闭客户端,不会关闭服务器,因为服务端是一直提供服务的
*/
TCP服务端
public class ServerDemo1 {
public static void main(String[] args) throws Exception{
// 1:建立服务器端的socket服务,需要一个端口
//ServerSocket(int port)
//创建绑定到指定端口的服务器套接字。
ServerSocket ss = new ServerSocket(12345);
while (true){
// 2:服务端没有直接流的操作,而是通过accept方法获取客户端对象,在通过获取到的客户端对象的流和客户端进行通信
Socket socket = ss.accept();
new TCPThread(socket).start();
}
}
}
class TCPThread extends Thread{
Socket socket;
public TCPThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
InetAddress inetAddress = socket.getInetAddress();
String hostName = inetAddress.getHostName();
System.out.println("用户:"+hostName+" 已上线! ");
try {
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:\\target\\" + hostName + "-" + System.currentTimeMillis() + ".jpg"));
while (true) {
// 3:通过客户端的获取流对象的方法,读取数据或者写入数据
// 获取通道中的输入流
InputStream inputStream = socket.getInputStream();
byte[] bytes = new byte[2048];
int length = 0;
while ((length = inputStream.read(bytes))!=-1){
// 4:通过流的对象可以对数据进行传输
bos.write(bytes,0, length);
bos.flush(); // 来自于通道中的类
}
// 获取通道中的输出流
OutputStream outputStream = socket.getOutputStream();
outputStream.write("图片已上传!!".getBytes());
outputStream.flush();
}
}catch (Exception e){
System.out.println("-----------------------");
System.out.println(hostName+" 用户已下线....");
System.out.println("-----------------------");
}
}
}
TCP客户端
/*
1:建立客户端的Socket服务,并明确要连接的服务器。
2:如果连接建立成功,就表明,已经建立了数据传输的通道.就可以在该通道通过IO进行数据的读取和写入.该通道称为Socket流,Socket流中既有读取流,也有写入流.
3:通过Socket对象的方法,可以获取这两个流
4:通过流的对象可以对数据进行传输
5:如果传输数据完毕,关闭资源
*/
public class ClientDemo1 {
public static void main(String[] args) throws Exception {
// 1:建立客户端的Socket服务,并明确要连接的服务器。
//Socket(String host, int port)
//创建流套接字并将其连接到指定主机上的指定端口号。
Socket socket = new Socket("192.168.22.24", 12345);
Scanner sc = new Scanner(System.in);
// 3:通过Socket对象的方法,可以获取这两个流
//获取通道中的输出流,将数据发送给服务端
OutputStream outputStream = socket.getOutputStream();
//获取通道中的输入流
InputStream inputStream = socket.getInputStream();
// E:\\李刚的对象.jpg
BufferedInputStream bis = null;
while (true){
try {
System.out.print("请输入要上传文件的路径:");
String address = sc.nextLine();
bis = new BufferedInputStream(new FileInputStream(address));
break;
}catch (Exception e){
System.out.println("路径不存在!重新输入!");
}
}
if(bis!=null){
byte[] bytes = new byte[2048];
int length = 0;
while ((length = bis.read(bytes))!=-1){
// 4:通过流的对象可以对数据进行传输
outputStream.write(bytes,0, length);
outputStream.flush(); // 来自于通道中的类
}
}
//关闭输出流,通知服务端读取结束
socket.shutdownOutput();
// 接收服务端的反馈
byte[] bytes = new byte[1024];
int length = inputStream.read(bytes);
String s = new String(bytes, 0, length);
System.out.println(s);
// 5:如果传输数据完毕,关闭资源
// outputStream.close();
socket.close();
}
}
UDP和TCP区别
TCP:是一种面向连接的协议,它在数据传输开始之前需要建立一个连接,确保数据传输的可靠性,传输较慢。
UDP:是一种无连接的协议,它不需要建立连接就可以直接发送数据,传输快。
标签:socket,public,static,线程,new,day19,String
From: https://www.cnblogs.com/flxf/p/18475535