返回顶部
首页 > 资讯 > 精选 >Java网络编程中线程的使用
  • 380
分享到

Java网络编程中线程的使用

2023-06-20 14:06:04 380人浏览 独家记忆
摘要

本篇内容介绍了“Java网络编程中线程的使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!目录运行线程回调同步方法同步块死锁优先级暂停可以对

本篇内容介绍了“Java网络编程线程的使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

目录
  • 运行线程

    • 回调

    • 同步方法

    • 同步块

    • 优先级

    • 暂停

      • 可以对io阻塞

      • 可以对同步对象阻塞

      • 可以放弃

      • 可以休眠

      • 可以连接另一个线程

      • 可以等待一个对象

      • 可以结束

    • 可以被更高优先级线程抢占

    运行线程

    创建Thread的子类

    public class ThreadChild extends Thread {    @Override    public void run() {        while (true) {            System.out.println("run");        }    }}
    public class Test {    public static void main(String[] args) throws Exception {        ThreadChild t = new ThreadChild();        t.start();    }}

    创建Thread传入Runnable接口实现类

    public class RunnableImpl implements Runnable {    @Override    public void run() {        while (true) {            System.out.println("run");        }    }}
    public class Test {    public static void main(String[] args) throws Exception {        Thread t = new Thread(new RunnableImpl());        t.start();    }}

    回调

    ExecutorService线程池的Submit()可接收Runnable或者Callable.Callable执行结束后有返回值,Runnable执行结束后没有返回值.可以通过submit的返回对象Future的get方法获取返回返回值,需要注意的是get方法是一个阻塞方法.若线程没有执行完毕,则会阻塞get()直到线程执行结束后返回数据.

    public static void main(String[] args) throws Exception {        ExecutorService executorService = Executors.newFixedThreadPool(10);        Future<Integer> future = executorService.submit(() -> {            TimeUnit.SECONDS.sleep( 3);            return 1;        });        Future<?> future2 = executorService.submit(() -> {        });        Future<String> future3 = executorService.submit(() -> {        }, "aaa");        System.out.println(future.get());        System.out.println(future2.get());        System.out.println(future3.get());    }

    同步方法

    synchronized关键字和方法组合使用后,该方法是一个同步方法。同步方法都有一个隐试的锁,多个线程同时执行该方法时,只能顺序执行,未强到锁的线程处于阻塞状态。另外静态方法和非静态方法使用的是不同的锁,非静态方法的锁是对象锁,若两个线程通过两个该类的对象调用那么互不影响。静态方法是类锁,即本类的Class对象。同步方法无法指定锁资源,要么是this锁,要么是Class锁。

    public class Test {    public static void main(String[] args) throws Exception {        Test test = new Test();        Thread t1 = new Thread(()->{            test.synFunction();        });        Thread t2 = new Thread(()->{            test.synFunction();        });        t1.start();        t2.start();    }    public synchronized void synFunction(){        try {            System.out.println("-------------");            TimeUnit.SECONDS.sleep(3);        }catch (Exception e) {}            }}
    public class Test {    public static void main(String[] args) throws Exception {        Thread t1 = new Thread(()->{            Test.synFunction();        });        Thread t2 = new Thread(()->{            Test.synFunction();        });        t1.start();        t2.start();    }    public static synchronized void synFunction(){        try {            System.out.println("-------------");            TimeUnit.SECONDS.sleep(3);        }catch (Exception e) {}            }}

    同步块

    同步代码块可以指定锁对象,非静态方法可以指定任意的对象锁,或者任意的类锁。但静态方法只能使用任意的类锁。

    public class Test {    public static void main(String[] args) throws Exception {        Test lock = new Test();        Thread t1 = new Thread(() -> {            lock.synFunction();        });        Thread t2 = new Thread(() -> {            lock.synFunction();        });        t1.start();        t2.start();    }    public void synFunction() {        synchronized (this) {//对象锁            try {                System.out.println("-------------");                TimeUnit.SECONDS.sleep(3);            } catch (Exception e) {            }        }    }}
    public class Test {    public static void main(String[] args) throws Exception {        Test lock1 = new Test();        Test lock2 = new Test();        Thread t1 = new Thread(() -> {            lock1.synFunction(lock1);        });        Thread t2 = new Thread(() -> {            lock2.synFunction(lock2);        });        t1.start();        t2.start();    }    public void synFunction(Object lock) {        synchronized (lock) {//对象锁            try {                System.out.println("-------------");                TimeUnit.SECONDS.sleep(3);            } catch (Exception e) {            }        }    }}
    public class Test {    public static void main(String[] args) throws Exception {        Test lock1 = new Test();        Test lock2 = new Test();        Thread t1 = new Thread(() -> {            lock1.synFunction();        });        Thread t2 = new Thread(() -> {            lock2.synFunction();        });        t1.start();        t2.start();    }    public void synFunction() {        synchronized (Test.class) {//类锁            try {                System.out.println("-------------");                TimeUnit.SECONDS.sleep(3);            } catch (Exception e) {            }        }    }}
    public class Test {    public static void main(String[] args) throws Exception {        Thread t1 = new Thread(() -> {            Test.synFunction();        });        Thread t2 = new Thread(() -> {            Test.synFunction();        });        t1.start();        t2.start();    }    public static void synFunction() {        synchronized (Object.class) {//类锁            try {                System.out.println("-------------");                TimeUnit.SECONDS.sleep(3);            } catch (Exception e) {            }        }    }}

    死锁

    当多个线程竞争锁时,可能会导致死锁。一个线程由于没有得到一个锁而阻塞它也不会释放已经获取的锁。方法1获取锁的顺序是Test.class,Object.class。方法2获取锁的顺序是Object.class,Test.class。程序会陷入死锁。

    public class Test {    public static void main(String[] args) throws Exception {        Thread t1 = new Thread(() -> {            Test.synFunction1();        });        Thread t2 = new Thread(() -> {             Test.synFunction2();        });        t1.start();        t2.start();    }    public static void synFunction1() {        synchronized (Test.class) {// 类锁            try {                System.out.println("synFunction1-------------AAAAAAAAAAAAA");                synchronized (Object.class) {// 类锁                    try {                        System.out.println("synFunction1-------------bbbbbbbbbbbbb");                    } catch (Exception e) {                    }                }            } catch (Exception e) {            }        }        }    public static void synFunction2() {        synchronized (Object.class) {// 类锁            try {                System.out.println("synFunction2-------------AAAAAAAAAAAAA");            } catch (Exception e) {            }            synchronized (Test.class) {// 类锁                try {                    System.out.println("synFunction2-------------bbbbbbbbbbbbb");                } catch (Exception e) {                }            }        }    }}

    优先级

    不是所有线程创建时都是均等的,每个线程都有一个优先级,指定从0-10的整数。当多个线程运行时,虚拟机通常只运行最高优先级的线程,但这并不是一个严格的规则。在Java中10是最高优先级,0是最低优先级。默认优先级为5.并不是所有操作系统都支持这11个优先级。例如windows只有7个优先级。优先级(1,2)(3,4)(6,7)(8,9)会做同样的处理。

    public class Test {    public static void main(String[] args) throws Exception {        Thread t1 = new Thread(() -> {            Test.synFunction("aaaaaaaaaaa");        });        Thread t2 = new Thread(() -> {             Test.synFunction("bbbbbbbbbb");        });        t2.setPriority(9);        t1.setPriority(1);        t1.start();        t2.start();    }    public static void synFunction(String name) {        System.out.println(name+"--------------");    }}

    暂停

    为了能让其他线程有机会运行,一个线程有8中方式可以暂停或者指示它准备暂停。

    可以对IO阻塞

    要让网络程序中的线程自动放弃CPU控制权,最常见的方式是IO阻塞。由于CPU比网络和磁盘快的多,网络程序经常会在等待数据从网络到达或向网络发送数据时阻塞。即使只阻塞几毫秒,这一点时间也足够其他线程用来完成重要的任务。

    可以对同步对象阻塞

    线程在进入一个同步方法或代码块时也会阻塞。如果这个线程没有所同步对象的锁,而其他线程拥有这个锁,这个线程就会暂停,直到锁被释放为止。如果这个锁永远不会释放,那么这个线程会永久停止。

    可以放弃

    调用Thread.yield()静态方法可以做到显试的放弃线程控制权,这将通知虚拟机,可以优先执行其他线程。放弃并不会释放这个线程拥有的锁,因此在理想情况下被放弃的线程不要做任何的同步。如果等待运行的其他线程都是因为这个线程所拥有的同步资源而阻塞,那么这些线程将不能运行。实际上,控制权将回到唯一可以运行的线程,即刚刚放弃的这个线程,这很大程度上失去了放弃的意义。

    public class Test {    public static void main(String[] args) throws Exception {        Thread t1 = new Thread(() -> {            Test.synFunction("aaaaaaaaaaa");        });        Thread t2 = new Thread(() -> {            Test.synFunction2("bbbbbbbbbb");        });        t1.start();        t2.start();    }    public static void synFunction(String name) {        for (int i = 0;; i++) {            Thread.yield();            System.out.println(name + "--------------" + i);        }    }    public static void synFunction2(String name) {        for (int i = 0;; i++)            System.out.println(name + "--------------"+i);    }}
    可以休眠

    休眠是更有利的放弃方式。放弃只是表示线程愿意暂停,让其他有相同优先级的线程有机会运行,而进入休眠的线程有所不同,不管有没有其他线程准备运行,休眠线程都会暂停。这样一来,不只是其他有相同优先级的线程会得到机会,还会给较低优先级的线程运行机会。不过进入休眠的线程仍然拥有它已经获得得所有锁。因此其他需要相同锁得线程依然会阻塞,要避免在同步方法或块内让线程休眠。

    public class Test {    public static void main(String[] args) throws Exception {        Thread t1 = new Thread(() -> {            Test.synFunction("aaaaaaaaaaa");        });        Thread t2 = new Thread(() -> {            Test.synFunction2("bbbbbbbbbb");        });        t1.start();        t2.start();    }    public synchronized static void synFunction(String name) {        try {            System.out.println(name);            Thread.sleep(1000 * 10);        } catch (Exception e) {        }    }    public synchronized static void synFunction2(String name) {        System.out.println(name);    }}
    package com.datang.bingxiang.demo;import java.util.concurrent.TimeUnit;public class Test {    public static void main(String[] args) throws Exception {        Thread t1 = new Thread(() -> {            Test.synFunction("aaaaaaaaaaa");        });        Thread t2 = new Thread(() -> {            Test.synFunction2("bbbbbbbbbb");        });        t1.start();        t2.start();    }    public synchronized static void synFunction(String name) {        try {            System.out.println(name);            Thread.sleep(1000 * 3, 999999);//3000毫秒+999999毫秒(第二个参数不能超过999999,也就是不能超过1毫秒)        } catch (Exception e) {            System.out.println(e);        }    }    public synchronized static void synFunction2(String name) {        System.out.println(name);    }}
    可以连接另一个线程

    连接线程(既调用join()方法得线程A)等待被连接的线程(join()方法所属的线程对象B)执行完毕后才会执行。在A线程调用B线程的join()A线程会等待B线程执行结束后才会继续执行。要注意的是A线程并不会释放已经获取的锁资源。

    public class Test {    public static void main(String[] args) throws Exception {        Thread t2 = new Thread(() -> {            Test.synFunction2("bbbbbbbbbb");        });        Thread t1 = new Thread(() -> {            Test.synFunction("aaaaaaaaaaa",t2);        });                t1.start();        t2.start();    }    public  static void synFunction(String name,Thread t) {        try {            t.join();            //t.join(1000);            //t.join(1000,999999);        } catch (InterruptedException e) {            e.printStackTrace();        }        for (int i = 0; i < 5; i++) {            System.out.println(name);        }    }    public  static void synFunction2(String name) {        try {            Thread.sleep(1000*3);        } catch (InterruptedException e) {            e.printStackTrace();        }        for (int i = 0; i < 5; i++) {            System.out.println(name);        }    }}
    可以等待一个对象

    线程可以等待一个它锁定的对象.在等待时,它会释放这个对象的锁并暂停,直到它得到其他线程的通知.另一个线程以某种方式修改这个对象,通知等待对象的线程,然后继续执行.等待会暂停执行,直到一个对象或资源到达某种状态.实际上,要等待某个特定的对象,希望暂停的线程首先必须使用synchronized获得这个对象的锁,然后调用这个对象的三个重载wait()方法之一.

    public class Demo {    public static void main(String[] args) throws Exception {        Demo d = new Demo();        Thread t1 = new Thread(() -> {            d.a();        });        Thread t2 = new Thread(() -> {            d.b();        });        t1.start();        t2.start();    }    boolean flag = true;    public synchronized void a() {        try {            while (true) {                if (flag) {                    System.out.println("执行AAAAAAAAAAA");                    flag = false;                } else {                    wait();//等待,不限制等待时间                    //wait(1000);//等待指定的时间,没有被notify唤醒也可以自己退出等待                    //wait(1000,999999);//毫秒+纳秒的等待时间                }                notify();            }        } catch (Exception e) {        }    }    public synchronized void b() {        try {            while (true) {                if (!flag) {                    System.out.println("执行BBBBBBBBBBB");                    flag = true;                } else {                    wait();                }                notify();            }        } catch (Exception e) {        }    }}
    可以结束

    线程要以合理的方式放弃CPU控制权,一种方式是结束.当run()方法返回线程时,线程将撤销,其他线程可以接管CPU.在网络应用程序中,包装一个阻塞操作的线程往往会这么做,例如线程从服务器下载一个文件,这样应用程序的其他部分就不会被阻塞.另一方面,如果run()方法太简单,总是很快结束,而不会紫色,那就存在一个很实际的问题:到底有没有必要生成一个线程.虚拟机在建立和撤销线程时会有很大的开销.如果线程会在极端的时间内结束,那么使用一次简单的方法调用而不是单独的线程可能会结束的更快.

    可以被更高优先级线程抢占

    Thread的setPriority(int priority)设置线程的优先级.

    “Java网络编程中线程的使用”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

    --结束END--

    本文标题: Java网络编程中线程的使用

    本文链接: https://lsjlt.com/news/297417.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    猜你喜欢
    • Java网络编程中线程的使用
      本篇内容介绍了“Java网络编程中线程的使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!目录运行线程回调同步方法同步块死锁优先级暂停可以对...
      99+
      2023-06-20
    • Java网络编程实现多线程聊天
      本文实例为大家分享了Java网络编程实现多线程聊天的具体代码,供大家参考,具体内容如下 聊天程序如果是单线程,会导致没人只能说一句,并且说了以后,必须等到另一个人的回复,才能说第二句...
      99+
      2024-04-02
    • Java 网络编程
      Java 网络编程   目录 Java 网络编程   Socket 编程 ServerSocket 类的方法 Socket 类的方法   InetAddress 类的方法 Socket 客户端实例 Socket 服务端实例     网络编...
      99+
      2023-10-09
      java
    • Java网络编程UDP实现多线程在线聊天
      本文实例为大家分享了Java实现多线程在线聊天的具体代码,供大家参考,具体内容如下 上一篇博客通过UDP实现了聊天,但只能单方面发送消息,这次实现了多线程在线聊天,也就是可以双方互发...
      99+
      2024-04-02
    • Java中怎么使用NIO实现网络编程
      本篇文章为大家展示了Java中怎么使用NIO实现网络编程,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。为什么需要NIO使用Java编写过Socket程序的同学一定都知道Socket和SocketSe...
      99+
      2023-06-17
    • Java网络编程怎么实现多线程聊天
      这篇文章将为大家详细讲解有关Java网络编程怎么实现多线程聊天,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。聊天程序如果是单线程,会导致没人只能说一句,并且说了以后,必须等到另一个人的回复,才能说第二句。...
      99+
      2023-06-20
    • Java网络编程 - 网络编程介绍 - 网络通信三要素
      文章目录 网络编程网络编程介绍网络通信三要素要素一: IP地址IP地址基本介绍IP地址的操作类 要素二: 端口号要素三: 协议TCP协议UDP协议 网络编程 网络...
      99+
      2023-09-07
      网络 java 网络协议
    • 怎么在Java中利用网络编程模拟在线聊天
      本篇文章为大家展示了怎么在Java中利用网络编程模拟在线聊天,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。1、前提知识需要知道简单的IO流操作,以及简单的UDP发送数据包的原理。需要用到的类:Dat...
      99+
      2023-06-15
    • iOS网络编程AFNetworking使用
      AFNetworking是一个基于iOS和OS X的开源网络编程库,它提供了一套简单易用的API,用于处理网络请求和响应。以下是使用...
      99+
      2023-09-28
      iOS
    • 详解Java网络编程
      目录一、网络编程1.1、概述1.2、计算机网络基础1.3、网络通信要素概述1.4、IP地址和端口号(组合就是网络套接字)1.5、网络协议1.6、三次握手与四次挥手二、TCP网络编程2...
      99+
      2024-04-02
    • Java 网络编程总结
      目录1、IP地址2、端口3、通信协议3.1 TCP/IP协议簇:实际上是一组协议3.2 TCP UDP对比3.3 TCP实现聊天3.4 TCP文件上传3.5 UDP消息发送3.6 U...
      99+
      2024-04-02
    • Java 网络编程基础
      文章目录 前言什么是网络编程网络编程基础知识网络通讯流程长连接和短连接Socket Java 网络编程总结 前言 一个网络请求、服务之间的调用都需要进行网络通讯,在日常开发时我们可能并不会关心我们的服务端是怎么接收到请求的、...
      99+
      2023-08-16
      java 网络 开发语言
    • Java 网络编程socket编程等详解
      网络编程是指编写运行在多个设备(计算机)的程序,这些设备都通过网络连接起来。java.net包中J2SE的API包含有类和接口,它们提供低层次的通信细节。你可以直接使用这些类和接口,来专注于解决问题,而不用关注通信细节。java.net包中...
      99+
      2023-05-31
      java 网络编程 socket编程
    • Python的requests网络编程包使用教程
      早就听说requests的库的强大,只是还没有接触,今天接触了一下,发现以前使用urllib,urllib2等方法真是太搓了…… 这里写些简单的使用初步作为一个记录 一、下载 官方项目页: https:/...
      99+
      2022-06-04
      网络编程 教程 Python
    • Java多线程编程如何使用
      本篇内容主要讲解“Java多线程编程如何使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java多线程编程如何使用”吧!Process和Thread程序是指令和数据的有序集合, 本身没有运行的...
      99+
      2023-06-22
    • 如何使用C++中的网络编程函数?
      如何使用C++中的网络编程函数?在现代社会中,网络已经成为了人们生活中不可或缺的一部分。在软件开发领域中,网络编程更是其中的重要组成部分。C++作为一种强大的编程语言,提供了丰富的网络编程函数和库,使得开发者可以轻松地构建各种网络应用程序。...
      99+
      2023-11-18
      C++ 网络编程 函数使用
    • Java网络编程 - UDP通信
      文章目录 UDP通信快速入门一发一收多发多收广播组播 UDP通信 快速入门 UDP协议的特点: UDP是一种无连接、不可靠传输的协议。 将数据源IP、目的地IP和端口以及数据封装成数据包,大小限制在64KB内,直...
      99+
      2023-08-30
      java 网络 udp
    • Java网络编程 - TCP通信
      文章目录 TCP通信快速入门(一发一收)编写客户端代码编写服务器代码 多发多收多发多收(同时接受多个客户端)线程池优化 TCP通信 快速入门(一发一收) TCP协议回顾: TCP是一种面向连接,安全、可靠的...
      99+
      2023-08-16
      网络 tcp/ip java
    • 如何使用linux网络编程用到的网络函数
      本篇内容主要讲解“如何使用linux网络编程用到的网络函数”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何使用linux网络编程用到的网络函数”吧!一.概念介绍网络程序分为服务端程序和客户端程...
      99+
      2023-06-09
    • Java网络编程:纵横网络四海的利器
      主要特性: 协议支持:Java支持广泛的网络协议,包括TCP、UDP、HTTP和FTP,使开发者能够构建各种网络应用程序。 面向对象:Java网络编程遵循面向对象编程原则,提供了一组易于使用的类和接口,简化了网络操作的实现。 多线程:J...
      99+
      2024-03-15
      网络编程
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作