JAVA135-185

多线程

多线程的第一种启动方式
1.自己定义一个类继承Thread
2.重写run方法
3.创建子类的对象并启动线程

public class Demo {
    public static void main(String[] args) {
        Mythread t1=new Mythread();
        t1.start();//开启线程
    }


}

public class Mythread  extends  Thread{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("HelloWorld");
        }
    }
}

多线程的第二种启动方式
1.自己定义一个类实现Runnable接口
2.重写里面的run方法
3.创建自己的类的对象
4.创建一个Thread类的对象并开启线程

//创建MyRun的对象
/表示多线程要执行的任务
MyRun mr = new MyRun();
//创建线程对象
Thread t1 = new Thread(mr);
/开启线程
t1.start();
public void run(){
//书写线程要执行的代码
for (int i =0;i< 100;i++){
∥获取到当前线程的对象
Thread t = Thread.currentThread();
System.out.println(t.getName() + "Helloworld!");
}
}

多线程的第三种实现方式
特点可以获取到多线程运行的结果
1.创建一个柒MyCallable实现callable接口
2.重写ca11~是有返回值的表示多线程运行的结果
3.创建MyCallable的对象表示多线程要执行的任务
4.创建FutureTask的对象(作用管理多线程运行的结果)
5.创建Thread类的对象并启动(表示线程)

//创建MyCallable的对象表示多线程要执行的任务)
MyCallable mc = new MyCallable();
//创建FutureTask的对象(作用管理多线程运行的结果)
FutureTask<Integer> ft = new FutureTask<>(mc);
//创建线程的对象
Thread t1 = new Thread(ft);
//启动线程
t1.start();
//获取多线程运行的结果
Integer result = ft.get();
System.out.println(result);
public class MyCallable implements Callable<Integer> {
@Override
public Integer call() throws Exception {
//求1~100之间的和
int sum = 0;
for (int i = 1;i <= 100; i++){
sum = sum + i;
}
return sum;
}
}

多线程成员方法

在这里插入图片描述
返回此线程的名称
String getName()
设置线程的名字构造方法也可以设置名
void setName(String name)
细节
1、如果我们没有给线程设置名字线程也是有默认的名字的
格式Thread-x(x序号从e开始的
2、如果我们要给线程设置名字可以用set方法进行设置也可以构造方法设置
获取当前线程的对象
static Thread currentThread()
让线程休眠指定的时间单位为毫秒
static void sleep(long time)

让线程休眠指定的时间隐位为毫秒
static void sleep(long time)
细节
1、哪条线程执行到这个方法那么哪条线程就会在这里停留对应的时间
2、方法的参数就表示睡眠的时间单位毫秒
1秒=1000毫秒
3、当时间到了之后线程会自动的醒来继续执行下面的其他代码

线程优先级

在这里插入图片描述

eg卖票线程的安全问题需要解决线程同时抢的问题

在这里插入图片描述

package com.itheima.thread02;

public class ThreadDemo {
    public static void main(String[] args) {
        MyThread t1=new MyThread();
        MyThread t2=new MyThread();
        MyThread t3=new MyThread();
        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");
        t1.start();
        t2.start();
        t3.start();
    }
}

package com.itheima.thread02;

public class MyThread extends Thread {
  //表示所有
  static   int ticket = 0;//表示
static Object obj=new Object();





    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
           synchronized (obj){
               if (ticket < 100) {

                   ticket++;
                   System.out.println(getName() + "正在卖第" + ticket + "票");
               } else {
                   break;
               }

           }

        }
    }
}

同步方法

在这里插入图片描述

package com.itheima.thread02;

public class MyRunnable implements Runnable {
    int ticket = 0;

    @Override
    public void run() {
        while (true)
            if (extracted()) break;
    }

    private synchronized boolean extracted() {
        synchronized (MyRunnable.class) {
            if(ticket==100){
                return true;



            }else {
                ticket++;
                System.out.println(Thread.currentThread().getName()+"在卖"+ticket+"票");
            }
        }
        return false;
    }
}


package com.itheima.thread02;

public class ThreadDemo {
    public static void main(String[] args) {

        MyRunnable mr = new MyRunnable();
        Thread t1 = new Thread(mr);
        Thread t2 = new Thread(mr);
        Thread t3 = new Thread(mr);
        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");
        t1.start();
        t2.start();
        t3.start();




    }
}

LOCK锁

在这里插入图片描述

等待唤醒机制

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package com.itheima.waitmodify;

public class Cook extends  Thread{
    @Override
    public void run() {
        while (true){
            synchronized (Desk.lock){
                if(Desk.count==0){
                    break;
                }else{
                    if(Desk.foodFlag==1){

                        try {
                            Desk.lock.wait();
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }else{
                        System.out.println("厨师做了一碗面条");
                        Desk.foodFlag=1;
                        Desk.lock.notifyAll();
                    }
                }
            }
        }
    }
}

package com.itheima.waitmodify;

public class Foodile extends Thread {
    @Override
    public void run() {
        /*
        1.循环
        2.同步代码块
        3.判断共享数据是否到了末尾到了末尾
        4. 判断共享数据是否到了末尾(没有到末尾
         */


        while (true) {
            synchronized (Desk.lock) {
                if (Desk.count == 0) {
                    break;

                } else {
                    //先判断桌子上是否有面条。没有就等待,如果有就开吃
                    //吃完之后要唤醒厨师继续做把吃的总数-1  修改桌子的状态
                    if(Desk.foodFlag==0){
                        try {
                            Desk.lock.wait();//让当前线程跟锁绑定
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                        Desk.lock.notifyAll();
                    }else{

                        System.out.println("吃货正在吃面条还能吃+"+Desk.count+"wan");
                        Desk.lock.notifyAll();
                        Desk.count--;
                        Desk.foodFlag=0;
                    }




                }
            }
        }
    }
}

package com.itheima.waitmodify;

public class Desk {

    //作用控制生产者和消费者的执行

    public  static  int foodFlag=0; //是否有面条0有面条 1无面条
    //总个数
    public  static  int count=10;
    public  static Object lock=new Object();


}

阻塞队列实现等待唤醒机制

多线程的六种状态

在这里插入图片描述

红包

package com.itheima.test4cas1;

public class Test {
/*
微信中的抢红包也用到了多线程。
假设100块分成了3个包现在有5个人去抢。
其中红包是共享数据。
5个人是5条线程。
打印结果如下
XXX抢到了XXX元
XXX抢到了XXX元
XXX抢到了XXX元
XXX没抢到
XXX没抢到
 */
    public static void main(String[] args) {
    MyThread t1=new MyThread();
    MyThread t2=new MyThread();
    MyThread t3=new MyThread();
    MyThread t4=new MyThread();
    MyThread t5=new MyThread();
t1.setName("xaa1");
t2.setName("xaaQ");
t3.setName("xaa1qweqwe");
t4.setName("xaa1qwes");
t5.setName("xaasadsssssdsadas1");
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();

    }
}








package com.itheima.test4cas1;

import java.util.Random;

public class MyThread extends Thread {
    static double money = 200;
    static int count = 3;
    static final double MIN = 0.01;

    @Override
    public void run() {
        //循环
        //同步代码块
        //判断是否到末尾到了
        //判断是否到末尾没到
        //
        synchronized (MyThread.class) {
            if (count == 0) {//判断是否到末尾到了
                System.out.println(getName() + "没有抢到红包");
            } else {
                double prize = 0;
                //判断共享数据是否到了末尾没有到末尾
                //不能直接随机
                if (count == 1) {
                    prize = money;
                    //表示此时是最后一个红包
                    //就无需随机剩余的所有钱都是中奖金额
                } else {
                    //表示第一次第二次的中奖情况
                    Random r = new Random();
                    double bounds = money - (count - 1) * MIN;
                    prize = r.nextDouble(bounds);
                    if (prize < MIN) {
                        prize = MIN;
                    }
                }
                 money = money - prize;
                count--;
                System.out.println(getName()+"抢到了红包"+prize);


            }
        }
    }
}


抽奖箱抽奖

有一个抽奖池该抽奖池中存放了奖励的金额该抽奖池中的奖项为{10,5,20,50,100,200,500,800,2,80,300,700}
创建两个抽奖箱线程设置线程名称分别为“抽奖箱1”“抽奖箱2”
随机从抽奖池中获取奖项元素并打印在控制台上格式如下
每次抽出一个奖项就打印一个随机
抽奖箱1又产生了一个10元大奖
抽奖箱1又产生了一个100元大奖
抽奖箱1又产生了一个200元大奖
抽奖箱1又产生了一个800元大奖
抽奖箱2又产生了一个700元大奖

package com.itheima.Test5;

import java.util.ArrayList;
import java.util.Collections;

public class MyThread extends Thread{
   ArrayList<Integer> list;
   
    public MyThread(ArrayList<Integer> list) {
        this.list = list;
    }


    @Override
    public void run() {
 while (true){
     synchronized (MyThread.class){
         if(list.size()==0){
                break;
         }
         else{

             Collections.shuffle(list);

             Integer prize = list.remove(0);
             System.out.println(getName()+"又产生了一个"+prize+"大奖");
         }
     }
     try {
         Thread.sleep(10);
     } catch (InterruptedException e) {
         throw new RuntimeException(e);
     }
 }

    }
}

package com.itheima.Test5;

import java.util.ArrayList;
import java.util.Collections;

public class Test {
    //有一个抽奖池该抽奖池中存放了奖励的金额该抽奖池中的奖项为{10,5,20,50,100,200,500,800,2,80,300,700}
    //创建两个抽奖箱线程设置线程名称分别为“抽奖箱1”“抽奖箱2”
    //随机从抽奖池中获取奖项元素并打印在控制台上格式如下
    //每次抽出一个奖项就打印一个随机
    //抽奖箱1又产生了一个10元大奖
    //抽奖箱1又产生了一个100元大奖
    //抽奖箱1又产生了一个200元大奖
    //抽奖箱1又产生了一个800元大奖
    //抽奖箱2又产生了一个700元大奖
    public static void main(String[] args) {
        ArrayList<Integer> list=new ArrayList<>();
        Collections.addAll(list ,10,5,20,50,100,200,500,800,2,80,300,700);
        MyThread t1=new MyThread(list);
        MyThread t2=new MyThread(list);
        t1.setName("抽奖箱1");
        t2.setName("抽奖箱2");

        t2.start();
        t1.start();
    }
}

比较

package com.itheima.Test5;

import java.util.ArrayList;
import java.util.Collections;
import java.util.concurrent.Callable;

public class MyCallable implements Callable<Integer> {
   ArrayList<Integer> list;
   static ArrayList<Integer> list1=new ArrayList<>();
   static ArrayList<Integer> list2=new ArrayList<>();
    public MyCallable(ArrayList<Integer> list) {
        this.list = list;
    }




    @Override
    public Integer call() throws Exception {
        ArrayList<Integer> boxlist=new ArrayList<>();
        while (true){
            synchronized (MyCallable.class){
                if(list.size()==0){
                    System.out.println(Thread.currentThread().getName()+boxlist);
                    break;
                }
                else{

                    Collections.shuffle(list);

                    Integer prize = list.remove(0);
                  boxlist.add(prize);

//             System.out.println(getName()+"又产生了一个"+prize+"大奖");
                }
            }
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        if (boxlist.size()==0){
            return null;

        }else{return  Collections.max(boxlist);}

    }
}

线程池

在这里插入图片描述
在这里插入图片描述

ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor
(核心线程数量最大线程数量空闲线程最大存活时间任务队列创建线程工厂任务的拒绝策略
参数一核心线程数量
不能小于e
不能小于等于0最大数量>=核心线程数量
不能小于e
参数二最大线程数
参数三空闲线程最大存活时间
参数四时间单位
用TimeUnit指定
不能为nul1
参数五任务队列
不能为null
不能为nul1
参数六创建线程工厂
参数七任务的拒绝策略

最大并行数

在这里插入图片描述

网络编程

在这里插入图片描述

InetAdress

package com.itheima.MyInetAdressDemo;

import java.net.InetAddress;
import java.net.UnknownHostException;

public class MyInetAdressDemo1 {
    public static void main(String[] args) throws UnknownHostException {
        /*
        static InetAddress getByName(String host)    确定主机名称的IP地址。主机名称可以是机器名称也可以是IP地址
        String getHostName()                     获取此IP地址的主机名
        String getHostAddress()                   返回文本显示中的IP地址字符串
         */
        InetAddress address = InetAddress.getByName("DESKTOP-4LVLCVP");
        System.out.println(address);
        String name = address.getHostName();
        System.out.println(name);
        String ip = address.getHostAddress();
        System.out.println(ip);
    }
}

端口号

在这里插入图片描述

协议

在这里插入图片描述
在这里插入图片描述

package com.itheima.MyInetAdressDemo;

import java.io.IOException;
import java.net.*;

public class SendMessageDemo {
    public static void main(String[] args) throws IOException {
        //发送数据
        //1.创建DatagramSocket对象快递公司
        //细节
        //绑定端口以后我们就是通过这个端口往外发送数据
        //空参所有可用的端口中随机一个进行使用
        //有参指定端口号进行绑定
        DatagramSocket ds = new DatagramSocket();
        //2.打包数据
        String str = "你好威猛啊";
        byte[] bytes = str.getBytes();
        InetAddress address = InetAddress.getByName("127.0.0.1");
        int port = 10086;
        DatagramPacket dp = new DatagramPacket(bytes, bytes.length, address, port);
        //3.发送数据
        ds.send(dp);
        ds.close();



    }
}

练习

package com.itheima.UDPTEST;

import java.io.IOException;
import java.net.*;
import java.util.Scanner;

public class SendMessageDemo {
    public static void main(String[] args) throws IOException {
        //按照下面的要求实现程序
        //UDP发送数据数据来自于键盘录入直到输入的数据是886发送数据结束
        //UDP接收数据因为接收端不知道发送端什么时候停止发送故采用死循环接收
        //1.创建对象DatagramSocket
        DatagramSocket ds = new DatagramSocket();
        //2.打包数据
        Scanner sc = new Scanner(System.in);
        while (true) {
            System.out.println("请输入你要说的话");
            String str=sc.nextLine();
            if("886".equals(str)){
                break;
            }
            byte[] bytes = str.getBytes();
            InetAddress address = InetAddress.getByName("127.0.0.1");
            int port =10086;
            DatagramPacket dp = new DatagramPacket(bytes, bytes.length, address, port);
            //3发送数据
            ds.send(dp);
        }
        //4.释放资源
        ds.close();

    }
}
package com.itheima.UDPTEST;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class ReceiveMessageDemo {
    public static void main(String[] args) throws IOException {
        //1.创建对象DatagramSocket的对象
        DatagramSocket ds = new DatagramSocket(10086);
        //2.接受数据包
        byte[] bytes=new byte[1024];
        DatagramPacket dp=new DatagramPacket(bytes, bytes.length);
        while (true) {
            ds.receive(dp);
            //3.解析数据包
            byte[] data = dp.getData();
            int len = dp.getLength();
            String ip = dp.getAddress().getHostAddress();
            String name = dp.getAddress().getHostName();
            //打印数据
            System.out.println("ip wei " + ip + ",主机名为" + name + "的人发送了数据" + new String(data, 0, len));
        }


    }
}

Tcp发送和接收数据

package com.itheima.a05tcpDemo1;

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;

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

    //TCP协议发送数据
//1.创建Socket对象
//细节在创建对象的同时会连接服务端
// 如果连接不上代码会报错
    Socket socket =new Socket("127.0.0.1",10000);
//2.从连接通道中获取输出流
    OutputStream os = socket.getOutputStream();
    //写出数据
    os.write("你好你好".getBytes());
    //3.释放资源
    os.close();
    socket.close();
}
}

package com.itheima.a05tcpDemo1;

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
    public static void main(String[] args) throws IOException {
        //Tcp协议接收数据
        //1.创建对象SeverSocket
        ServerSocket ss = new ServerSocket(10000);
        //2.监听客户端链接
        Socket socket = ss.accept();
        //3.从链接通道中 获取输入流读取数据
        InputStream is = socket.getInputStream();
        int b;
        while ((b=is.read())!=-1){
            System.out.println((char) b);
        }

    }

}

三次握手四次挥手

在这里插入图片描述

多发多收


package com.itheima.a07Test1;

import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

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

        //1.创建对象绑定10000端口
        ServerSocket ss=new ServerSocket(10000);
        //2.等待客户端链接
        Socket socket = ss.accept();
        //3.读取数据
        InputStreamReader isr=new InputStreamReader(socket.getInputStream());
        int b;
        while((b= isr.read())!=-1){
            System.out.println((char)b);
        }
    //4.释放资源
    socket.close();
        ss.close();
    }
}

package com.itheima.a07Test1;

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;

public class Client {
    public static void main(String[] args) throws IOException {
        //客户端多次发送数据
        //服务器接受多次数据并打印
        //1.创建Socket对象并链接服务端
        Socket socket =new Socket("127.0.0.1",10000);
        //2.写数据
        Scanner sc = new Scanner(System.in);
        String str=sc.nextLine();
        System.out.println("请输入您要发送的信息");
        OutputStream os=socket.getOutputStream();
         os. write(str.getBytes());
         //3.释放资源
        socket.close();

    }
}

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: Java