线程状态、工具类

1、 聊天程序案例

单线程版本:

public class Server {
    public static void main(String[] args) {
		// 服务端
		
        // List<Socket> lists = new ArrayList<>();
        try {
            // System.out.println(InetAddress.getLocalHost().getAddress());
            // 192.168.78.1
            ServerSocket server = new ServerSocket(1223);
            Socket c = server.accept();
            System.out.println("有人上线");
            PrintWriter out = new PrintWriter(c.getOutputStream()); // 发信息
            BufferedReader br = new BufferedReader(new InputStreamReader(c.getInputStream())); // 收信息

            while (true){
                // 先收信息
                String msg = br.readLine();
                System.out.println(msg);

                // 发信息
                System.out.println("发信息:");
                String info = new Scanner(System.in).nextLine() + "\r\n";
                out.write(info);
                out.flush();
            }

            /* while (true){
                Socket c = server.accept(); // 中断
                list.add(c);
                System.out.println("有人连线");
            } */

        } catch (Exception e){
            e.printStackTrace();
        }
    }
}
public class Client {
    public static void main(String[] args) {
        // 客户端
        
        try {
            Socket c= new Socket("192.168.78.1",1223);
            PrintWriter out = new PrintWriter(c.getOutputStream()); // 发信息
            BufferedReader br = new BufferedReader(new InputStreamReader(c.getInputStream())); // 收信息

            while (true) {
                System.out.println("发信息");
                String msg = new Scanner(System.in).nextLine() + "\r\n";
                out.write(msg);
                out.flush();

                String info = br.readLine();
                System.out.println(info);
            }
        } catch (Exception e){
            e.printStackTrace();
        }
    }
}

实现效果:

在这里插入图片描述

多线程版本:Server、Client、Read接收类、Send发送类

	public class ChatUtil {
    private PrintWriter writer;
    private BufferedReader reader;
    private String title;

    public ChatUtil(PrintWriter writer, BufferedReader reader, String title) {
        this.writer = writer;
        this.reader = reader;
        this.title = title;
    }

     /*
        发信息
     */
    public void a(){
        while (true){
            // 发信息
            String info = title + ":" + new Scanner(System.in).nextLine() + "\r\n";
            writer.write(info);
            writer.flush();
        }
    }

    public void b(){
        while (true){
            try {
                // 先收信息
                String msg = reader.readLine();
                System.out.println(msg);
            } catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    public PrintWriter getWriter() {
        return writer;
    }

    public void setWriter(PrintWriter writer) {
        this.writer = writer;
    }

    public BufferedReader getReader() {
        return reader;
    }

    public void setReader(BufferedReader reader) {
        this.reader = reader;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
}

public class Server {
    public static void main(String[] args) {
        try {
            ServerSocket server = new ServerSocket(5595);
            Socket c = server.accept();
            PrintWriter writer = new PrintWriter(c.getOutputStream());
            BufferedReader reader = new BufferedReader(new InputStreamReader(c.getInputStream()));
            ChatUtil cu = new ChatUtil(writer,reader,"服务器");
            new Thread(cu::a).start();
            new Thread(cu::b).start();

        } catch (Exception e){
            e.printStackTrace();
        }
    }
}
public class Client {
    public static void main(String[] args) {

        try {
            Socket c = new Socket("localhost",5595);
            PrintWriter  writer = new PrintWriter(c.getOutputStream());
            BufferedReader reader = new BufferedReader(new InputStreamReader(c.getInputStream()));
            ChatUtil cu = new ChatUtil(writer,reader,"客户端");
            new Thread(cu::a).start();
            new Thread(cu::b).start();

        } catch (Exception e){
            e.printStackTrace();
        }
    }
}

实现效果:

在这里插入图片描述

2、 线程状态

  1. 新建(NEW):新创建了一个线程对象。
  2. 可运行(RUNNABLE):线程对象创建后,其他线程(比如main线程)调用了该对象的start() 方法。该状态的线程位于可运行线程池中,等待被线程调用选中,获取cpu的使用权。
  3. 运行(RUNNING):可运行状态(runnable)的线程获得了cpu的时间片(timeslice),执行程序代码。
  4. 阻塞(BLOCKED):阻塞状态是指线程因为某种原因放弃了cpu使用权,也即让出了cputimeslice,暂时停止运行,直到线程进入可运行(runnable)状态,才有机会再次获得cputimeslice转到运行(running)状态,阻塞的情况分三种:
    ① 等待阻塞:运行(running)的线程执行o.wait()方法,JVM会把该线程放入等待队列(waitting queue)中。
    ② 同步阻塞:运行(running)的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池(lock pool)中。
    ③ 其他阻塞:运行(running)的线程执行Thread.sleep(long ms) 或 t.join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep() 状态超时、join() 等待线程终止或者超时、或者I/O处理完毕时,线程重新转入可运行(runnable)状态。
  5. 死亡(DEAD):线程run()、main()方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。死亡的线程不可再次复生。

在这里插入图片描述

在这里插入图片描述

3、 线程优先级别

当程序分为多个线程运行时,每个线程都会得到一小段CPU时间来运行,运行时间结束后,将轮换另一个线程进入运行状态,JVM会优先选择优先级高的线程进入运行状态。但这并不意味着优先级底的线程得不到运行,JVM会自动对一段时间内没有得到时间片运行的线程提高优先级。
线程的优先级是由1-10之间的数字来表示的,数字1表示最低优先级,数字10表示最高优先级,默认优先级是5。
Thread类的setPriority() 方法可以设置线程的优先级,方法说明如下:
void setPriority (int newPriority)
该方法用于更改当前线程的优先级,优先级高的线程会优先运行,同样优先级的线程排在前面的会优先运行。newPriority为设置的优先级数字,如果该数字不在1-10范围之类,会抛出IllegalArgumentException异常(参数异常)。

void setPriority (int newPriority)

t.setPriority(Thread.MAX_PRIORITY);
t.setPriority(Thread.NORM_PRIORITY);
t.setPriority(Thread.MIN_PRIORITY);
int tp = t.getProority();

4、 线程名称设置

// 实现Runnable接口,重写run方法,将此类的实例作为Thread类的参数,来开启线程执行
        Th2 th2 = new Th2();
        
        // th2线程对象,"AA"是当前这个线程的名称
        Thread t1 = new Thread(th2,"AA");
        t1.setName("A线程");
        Thread t2 = new Thread(th2,"BB");

        FutureTask<Integer> f1 = new FutureTask<>(new Th6(10000));
        Thread t = new Thread(f1,"F1线程");
        
        FutureTask<Integer> f2 = new FutureTask<>(new Th6(100));
        Thread t2 = new Thread(f2,"f2线程");

5、 Timer TimerTask工具类

Timer类的常用其他方法:

cancel() 终止此计时器,丢弃所有当前已安排的任务。

purge() 从此计时器的任务队列中移除所有已取消的任务

schedule(TimerTask task, Date time) 安排在指定的时间执行指定的任务。

TimerTask类的常用其他方法:

cancel() 取消此计时器任务。

run() 此计时器任务要执行的操作。

scheduledExecutionTime() 返回此任务最近行的已安排执行时间。

public class TimerTest {
    public static void main(String[] args) throws ParseException {
        /*
            schedule和scheduleAtFixedRate的区别在于,如果指定开始执行的时间
            在当前系统运行时间之前,scheduleAtFixedRate会把过去的时间也作为周
            期执行,而schedule不会把过去的时间算上。
        */

        Timer t = new Timer();
        t.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.printf("%1$tF%1$tT%n", System.currentTimeMillis());
                // t.cancel();
            }
        }, 5000, 1000);

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyyy-MM-dd HH:mm:ss");
        t.schedule(new TimerTask() {
            @Override
            public void run() {
                t.cancel();
            }
        }, sdf.parse("2022-10-02 21:00:00"));

        Timer t2 = new Timer();
        TimerTask tt = new TimerTask() {
            @Override
            public void run() {
                System.out.println("hello world Timer");
                t2.cancel();
            }
        };
        t2.schedule(tt, 10000);
    }
}

public class T {
    public static void main(String[] args) {
        ScheduledExecutorService ses = new ScheduledThreadPoolExecutor(1);
        ses.scheduleAtFixedRate(() -> {
            System.out.println("hello");
        }, 5, 1, TimeUnit.SECONDS);
    }
}

6、 TimeUnit时间颗粒工具类

TimeUnit是java.util.concurrent包下面的一个类,表示给定单元粒度的时间段

  1. 主要作用
    时间颗粒度转换
    延时

  2. 常用的颗粒度
    TimeUnit.DAYS // 天
    TimeUnit.HOURS // 小时
    TimeUnit.MINUTES // 分钟
    TimeUnit.SECONDS // 秒
    TimeUnit.MILLISECONDS // 毫秒
    TimeUnit.NANOSECONDS // 毫微秒
    TimeUnit.MINCROSECONDS // 微秒

public long toMillis(long d)  // 转换成毫秒
    public long toSeconds(long d)  // 转换成秒
    public long toMinutes(long d)  // 转换成分钟
    public long toHours(long d)  // 转换成小时
    public long toDays(long d)  // 转换成天
        try{
        TimeUnit.DAYS.sleep(10);
    } catch(InterruptedException e){
            throw new RuntimeException(e);
    }
        try{
            Thread.sleep(10000);
    } catch(Exception e){
            e.printStackTrace();
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值