Java多线程程序设计

IMS/Softphone 开源项目启动 序:一直对网络 音视频通信很感兴趣,终于在今天决心要做一个windows下的开源软电话,并梦想最终做成一个像模像样的IMS客户端。作为Windows下的傻瓜程序员,对L/U下的开源项目即羡慕,又恐惧,每每在VS上编译标榜支持Windows的开源项目上恶梦连连。为什么Windwos下的资源那么匮乏呢,罢了罢了,也做回愚公吧。我不编译你的了,自己写一个。自己写一个能在VS平台上,舒舒服服编译的,舒舒服 阅读详情
一:理解多线程

多线程是这样一种机制,它允许在程序中并发执行多个指令流,每个指令流都称为一个线程,彼此间互相独立。 线程又称为轻量级进程,它和进程一样拥有独立的执行控制,由操作系统负责调度,区别在于线程没有独立的存储空间,而是和所属进程中的其它线程共享一个存储空间,这使得线程间的通信远较进程简单。

多个线程的执行是并发的,也就是在逻辑上“同时”,而不管是否是物理上的“同时”。如果系统只有一个CPU,那么真正的“同时”是不可能的,但是由于CPU的速度非常快,用户感觉不到其中的区别,因此我们也不用关心它,只需要设想各个线程是同时执行即可。
多线程和传统的单线程在程序设计上最大的区别在于,由于各个线程的控制流彼此独立,使得各个线程之间的代码是乱序执行的,由此带来的线程调度,同步等问题,将在以后探讨。

  二:在Java中实现多线程

我们不妨设想,为了创建一个新的线程,我们需要做些什么?很显然,我们必须指明这个线程所要执行的代码,而这就是在Java中实现多线程我们所需要做的一切!

真是神奇!Java是如何做到这一点的?通过类!作为一个完全面向对象的语言,Java提供了类 java.lang.Thread 来方便多线程编程,这个类提供了大量的方法来方便我们控制自己的各个线程,我们以后的讨论都将围绕这个类进行。

那么如何提供给 Java 我们要线程执行的代码呢?让我们来看一看 Thread 类。Thread 类最重要的方法是 run() ,它为Thread 类的方法 start() 所调用,提供我们的线程所要执行的代码。为了指定我们自己的代码,只需要覆盖它!

  方法一:继承 Thread 类,覆盖方法 run(),我们在创建的 Thread 类的子类中重写 run() ,加入线程所要执行的代码即可。下面是一个例子:

public class MyThread extends Thread {
 int count= 1, number;
 public MyThread(int num) {
  number = num;
  System.out.println("创建线程 " + number);
 }
 public void run() {
  while(true) {
   System.out.println("线程 " + number + ":计数 " + count);
   if(++count== 6) return;
  }
 }
 public static void main(String args[]) {
  for(int i = 0; i 〈 5; i++) new MyThread(i+1).start();
 }
}

这种方法简单明了,符合大家的习惯,但是,它也有一个很大的缺点,那就是如果我们的类已经从一个类继承(如小程序必须继承自 Applet 类),则无法再继承 Thread 类,这时如果我们又不想建立一个新的类,应该怎么办呢?

我们不妨来探索一种新的方法:我们不创建 Thread 类的子类,而是直接使用它,那么我们只能将我们的方法作为参数传递给 Thread 类的实例,有点类似回调函数。但是 Java 没有指针,我们只能传递一个包含这个方法的类的实例。那么如何限制这个类必须包含这一方法呢?当然是使用接口!(虽然抽象类也可满足,但是需要继承,而我们之所以要采用这种新方法,不就是为了避免继承带来的限制吗?)
Java 提供了接口 java.lang.Runnable 来支持这种方法。

  方法二:实现 Runnable 接口

Runnable 接口只有一个方法 run(),我们声明自己的类实现 Runnable 接口并提供这一方法,将我们的线程代码写入其中,就完成了这一部分的任务。但是 Runnable 接口并没有任何对线程的支持,我们还必须创建 Thread 类的实例,这一点通过 Thread 类的构造函数public Thread(Runnable target);来实现。下面是一个例子:

public class MyThread implements Runnable {
 int count= 1, number;
 public MyThread(int num) {
  number = num;
  System.out.println("创建线程 " + number);
 }
 public void run() {
  while(true) {
   System.out.println("线程 " + number + ":计数 " + count);
   if(++count== 6) return;
  }
 }
 public static void main(String args[]) {
  for(int i = 0; i 〈 5; i++) new Thread(new MyThread(i+1)).start();
 }
}

严格地说,创建 Thread 子类的实例也是可行的,但是必须注意的是,该子类必须没有覆盖 Thread 类的 run 方法,否则该线程执行的将是子类的 run 方法,而不是我们用以实现Runnable 接口的类的 run 方法,对此大家不妨试验一下。

  使用 Runnable 接口来实现多线程使得我们能够在一个类中包容所有的代码,有利于封装,它的缺点在于,我们只能使用一套代码,若想创建多个线程并使各个线程执行不同的代码,则仍必须额外创建类,如果这样的话,在大多数情况下也许还不如直接用多个类分别继承 Thread 来得紧凑。

  综上所述,两种方法各有千秋,大家可以灵活运用。

  下面让我们一起来研究一下多线程使用中的一些问题。
  三:线程的四种状态

  1. 新状态:线程已被创建但尚未执行(start() 尚未被调用)。

  2. 可执行状态:线程可以执行,虽然不一定正在执行。CPU 时间随时可能被分配给该线程,从而使得它执行。

  3. 死亡状态:正常情况下 run() 返回使得线程死亡。调用 stop()或 destroy() 亦有同样效果,但是不被推荐,前者会产生异常,后者是强制终止,不会释放锁。

  4. 阻塞状态:线程不会被分配 CPU 时间,无法执行。

  四:线程的优先级

线程的优先级代表该线程的重要程度,当有多个线程同时处于可执行状态并等待获得 CPU 时间时,线程调度系统根据各个线程的优先级来决定给谁分配 CPU 时间,优先级高的线程有更大的机会获得 CPU 时间,优先级低的线程也不是没有机会,只是机会要小一些罢了。

你可以调用 Thread 类的方法 getPriority() 和 setPriority()来存取线程的优先级,线程的优先级界于1(MIN_PRIORITY)和10(MAX_PRIORITY)之间,缺省是5(NORM_PRIORITY)。

  五:线程的同步

由于同一进程的多个线程共享同一片存储空间,在带来方便的同时,也带来了访问冲突这个严重的问题。Java语言提供了专门机制以解决这种冲突,有效避免了同一个数据对象被多个线程同时访问。

  由于我们可以通过 private 关键字来保证数据对象只能被方法访问,所以我们只需针对方法提出一套机制,这套机制就是 synchronized 关键字,它包括两种用法:synchronized 方法和 synchronized 块。

  1. synchronized 方法:通过在方法声明中加入 synchronized关键字来声明 synchronized 方法。如:

public synchronized void accessVal(int newVal);

  synchronized 方法控制对类成员变量的访问:每个类实例对应一把锁,每个 synchronized 方法都必须获得调用该方法的类实例的锁方能执行,否则所属线程阻塞,方法一旦执行,就独占该锁,直到从该方法返回时才将锁释放,此后被阻塞的线程方能获得该锁,重新进入可执行状态。这种机制确保了同一时刻对于每一个类实例,其所有声明为 synchronized 的成员函数中至多只有一个处于可执行状态(因为至多只有一个能够获得该类实例对应的锁),从而有效避免了类成员变量的访问冲突(只要所有可能访问类成员变量的方法均被声明为 synchronized)。

  在 Java 中,不光是类实例,每一个类也对应一把锁,这样我们也可将类的静态成员函数声明为 synchronized ,以控制其对类的静态成员变量的访问。

  synchronized 方法的缺陷:若将一个大的方法声明为synchronized 将会大大影响效率,典型地,若将线程类的方法 run() 声明为 synchronized ,由于在线程的整个生命期内它一直在运行,因此将导致它对本类任何 synchronized 方法的调用都永远不会成功。当然我们可以通过将访问类成员变量的代码放到专门的方法中,将其声明为 synchronized ,并在主方法中调用来解决这一问题,但是 Java 为我们提供了更好的解决办法,那就是 synchronized 块。

  2. synchronized 块:通过 synchronized关键字来声明synchronized 块。语法如下:

synchronized(syncObject) {
//允许访问控制的代码
}

synchronized 块是这样一个代码块,其中的代码必须获得对象 syncObject (如前所述,可以是类实例或类)的锁方能执行,具体机制同前所述。由于可以针对任意代码块,且可任意指定上锁的对象,故灵活性较高。
  六:线程的阻塞

为了解决对共享存储区的访问冲突,Java 引入了同步机制,现在让我们来考察多个线程对共享资源的访问,显然同步机制已经不够了,因为在任意时刻所要求的资源不一定已经准备好了被访问,反过来,同一时刻准备好了的资源也可能不止一个。为了解决这种情况下的访问控制问题,Java 引入了对阻塞机制的支持。

阻塞指的是暂停一个线程的执行以等待某个条件发生(如某资源就绪),学过操作系统的同学对它一定已经很熟悉了。Java 提供了大量方法来支持阻塞,下面让我们逐一分析。

  1. sleep() 方法:sleep() 允许 指定以毫秒为单位的一段时间作为参数,它使得线程在指定的时间内进入阻塞状态,不能得到CPU 时间,指定的时间一过,线程重新进入可执行状态。

  典型地,sleep() 被用在等待某个资源就绪的情形:测试发现条件不满足后,让线程阻塞一段时间后重新测试,直到条件满足为止。

  2. suspend() 和 resume() 方法:两个方法配套使用,suspend()使得线程进入阻塞状态,并且不会自动恢复,必须其对应的resume() 被调用,才能使得线程重新进入可执行状态。典型地,suspend() 和 resume() 被用在等待另一个线程产生的结果的情形:测试发现结果还没有产生后,让线程阻塞,另一个线程产生了结果后,调用 resume() 使其恢复。

  3. yield() 方法:yield() 使得线程放弃当前分得的 CPU 时间,但是不使线程阻塞,即线程仍处于可执行状态,随时可能再次分得 CPU 时间。调用 yield() 的效果等价于调度程序认为该线程已执行了足够的时间从而转到另一个线程。

  4. wait() 和 notify() 方法:两个方法配套使用,wait() 使得线程进入阻塞状态,它有两种形式,一种允许 指定以毫秒为单位的一段时间作为参数,另一种没有参数,前者当对应的 notify() 被调用或者超出指定时间时线程重新进入可执行状态,后者则必须对应的 notify() 被调用。

初看起来它们与 suspend() 和 resume() 方法对没有什么分别,但是事实上它们是截然不同的。区别的核心在于,前面叙述的所有方法,阻塞时都不会释放占用的锁(如果占用了的话),而这一对方法则相反。

  上述的核心区别导致了一系列的细节上的区别。

首先,前面叙述的所有方法都隶属于 Thread 类,但是这一对却直接隶属于 Object 类,也就是说,所有对象都拥有这一对方法。初看起来这十分不可思议,但是实际上却是很自然的,因为这一对方法阻塞时要释放占用的锁,而锁是任何对象都具有的,调用任意对象的 wait() 方法导致线程阻塞,并且该对象上的锁被释放。而调用 任意对象的notify()方法则导致因调用该对象的 wait() 方法而阻塞的线程中随机选择的一个解除阻塞(但要等到获得锁后才真正可执行)。

其次,前面叙述的所有方法都可在任何位置调用,但是这一对方法却必须在 synchronized 方法或块中调用,理由也很简单,只有在synchronized 方法或块中当前线程才占有锁,才有锁可以释放。同样的道理,调用这一对方法的对象上的锁必须为当前线程所拥有,这样才有锁可以释放。因此,这一对方法调用必须放置在这样的 synchronized 方法或块中,该方法或块的上锁对象就是调用这一对方法的对象。若不满足这一条件,则程序虽然仍能编译,但在运行时会出现IllegalMonitorStateException 异常。

wait() 和 notify() 方法的上述特性决定了它们经常和synchronized 方法或块一起使用,将它们和操作系统的进程间通信机制作一个比较就会发现它们的相似性:synchronized方法或块提供了类似于操作系统原语的功能,它们的执行不会受到多线程机制的干扰,而这一对方法则相当于 block 和wakeup 原语(这一对方法均声明为 synchronized)。它们的结合使得我们可以实现操作系统上一系列精妙的进程间通信的算法(如信号量算法),并用于解决各种复杂的线程间通信问题。

  关于 wait() 和 notify() 方法最后再说明两点:

第一:调用 notify() 方法导致解除阻塞的线程是从因调用该对象的 wait() 方法而阻塞的线程中随机选取的,我们无法预料哪一个线程将会被选择,所以编程时要特别小心,避免因这种不确定性而产生问题。

第二:除了 notify(),还有一个方法 notifyAll() 也可起到类似作用,唯一的区别在于,调用 notifyAll() 方法将把因调用该对象的 wait() 方法而阻塞的所有线程一次性全部解除阻塞。当然,只有获得锁的那一个线程才能进入可执行状态。

谈到阻塞,就不能不谈一谈死锁,略一分析就能发现,suspend() 方法和不指定超时期限的 wait() 方法的调用都可能产生死锁。遗憾的是,Java 并不在语言级别上支持死锁的避免,我们在编程中必须小心地避免死锁。

以上我们对 Java 中实现线程阻塞的各种方法作了一番分析,我们重点分析了 wait() 和 notify() 方法,因为它们的功能最强大,使用也最灵活,但是这也导致了它们的效率较低,较容易出错。实际使用中我们应该灵活使用各种方法,以便更好地达到我们的目的。

  七:守护线程

守护线程是一类特殊的线程,它和普通线程的区别在于它并不是应用程序的核心部分,当一个应用程序的所有非守护线程终止运行时,即使仍然有守护线程在运行,应用程序也将终止,反之,只要有一个非守护线程在运行,应用程序就不会终止。守护线程一般被用于在后台为其它线程提供服务。

  可以通过调用方法 isDaemon() 来判断一个线程是否是守护线程,也可以调用方法 setDaemon() 来将一个线程设为守护线程。

  八:线程组

线程组是一个 Java 特有的概念,在 Java 中,线程组是类ThreadGroup 的对象,每个线程都隶属于唯一一个线程组,这个线程组在线程创建时指定并在线程的整个生命期内都不能更改。你可以通过调用包含 ThreadGroup 类型参数的 Thread 类构造函数来指定线程属的线程组,若没有指定,则线程缺省地隶属于名为 system 的系统线程组。

在 Java 中,除了预建的系统线程组外,所有线程组都必须显式创建。在 Java 中,除系统线程组外的每个线程组又隶属于另一个线程组,你可以在创建线程组时指定其所隶属的线程组,若没有指定,则缺省地隶属于系统线程组。这样,所有线程组组成了一棵以系统线程组为根的树。

Java 允许我们对一个线程组中的所有线程同时进行操作,比如我们可以通过调用线程组的相应方法来设置其中所有线程的优先级,也可以启动或阻塞其中的所有线程。

  Java 的线程组机制的另一个重要作用是线程安全。线程组机制允许我们通过分组来区分有不同安全特性的线程,对不同组的线程进行不同的处理,还可以通过线程组的分层结构来支持不对等安全措施的采用。Java 的 ThreadGroup 类提供了大量的方法来方便我们对线程组树中的每一个线程组以及线程组中的每一个线程进行操作。

  九:总结

在本文中,我们讲述了 Java 多线程编程的方方面面,包括创建线程,以及对多个线程进行调度、管理。我们深刻认识到了多线程编程的复杂性,以及线程切换开销带来的多线程程序的低效性,这也促使我们认真地思考一个问题:我们是否需要多线程?何时需要多线程?

多线程的核心在于多个代码块并发执行,本质特点在于各代码块之间的代码是乱序执行的。我们的程序是否需要多线程,就是要看这是否也是它的内在特点。

假如我们的程序根本不要求多个代码块并发执行,那自然不需要使用多线程;假如我们的程序虽然要求多个代码块并发执行,但是却不要求乱序,则我们完全可以用一个循环来简单高效地实现,也不需要使用多线程;只有当它完全符合多线程的特点时,多线程机制对线程间通信和线程管理的强大支持才能有用武之地,这时使用多线程才是值得的。
SIP协议详解:从核心原理到GB28181实战,构建实时通信基石 会话初始协议(SIP)是互联网工程任务组(IETF)制定的应用层控制协议,构成了实时音视频通信的信令基石。其核心原理借鉴了HTTP的请求-响应模型,通过文本协议定义会话的发起、修改与终止流程,并依赖SDP协议进行媒体能力协商。这一设计赋予了SIP协议极高的灵活性和可扩展性,使其技术价值超越了传统VoIP电话,成为构建企业IP通信、软交换平台乃至物联网信令交互的关键技术。在安防监控等特定行业,SIP协议通过深度定制化,支撑了如国标GB/T 28181等大规模联网系统的信令传输与控制。本文聚焦于SIP协议的核心 阅读详情

相关推荐

Windows系统下LaTeX环境搭建与编辑器配置全攻略

本文详细介绍了在Windows系统下搭建LaTeX环境的完整流程,包括TeX Live的安装、TeXStudio编辑器的配置优化以及常见问题排查。特别针对中文用户推荐使用清华镜像源加速下载,并提供了XeLaTeX编译器配置、中文支持等实用技巧,帮助用户快速上手LaTeX文档编写。

weixin_42554408的博客 449

java.lang.Thread

java.lang.Thread 位于java.lang包下的Thread是非常重要的线程类,它实现了Runnable接口。本篇文章围绕Thread具体介绍一下Java线程的概念和Thread类中常用的方法 1.线程的状态 线程从创建到最终的消亡, 要经历若干个状态。一般来说,线程包括以下几个状态:创建(new), 可运行(runnable), 阻塞(blocked), time waiting,...

wintershii的博客 1556

保姆级教程:用STM32CubeMX给STM32F407配置RTC秒中断,并解决掉电时间丢失问题

本文详细介绍了如何使用STM32CubeMX为STM32F407配置RTC秒中断,并解决掉电时间丢失问题。通过硬件原理与软件配置的双视角解析,帮助开发者实现精确计时与时间持久化,适用于物联网设备和工业控制器等场景。

weixin_42519733的博客 137

thread类 java_java.lang.Thread类详解

java.lang.Thread类详解一、前言位于java.lang包下的Thread类是非常重要的线程类,它实现了Runnable接口,今天我们来学习一下Thread类,在学习Thread类之前,先介绍与线程相关知识:线程的几种状态、上下文切换,然后接着介绍Thread类中的方法的具体使用。二、线程的状态在正式学习Thread类中的具体方法之前,我们先来了解一下线程有哪些状态,这个将会有助于后面...

weixin_39805255的博客 688

开关电源设计实战:如何用AP值快速选型磁芯(附计算公式推导)

本文为开关电源工程师提供了基于AP值的磁芯快速选型实战指南。文章深入解析了AP值作为磁芯‘功率吞吐量’指标的核心物理意义,并通过详细的公式推导和24W反激电源设计实例,手把手演示如何利用AP值计算公式,结合电流密度、窗口利用率等关键参数,从众多磁芯型号中高效筛选出合适型号,同时强调了选型后的关键校验步骤与常见误区。

weixin_29234239的博客 878

手把手教你实现阿克曼ROS小车的运动控制

本文详细介绍了如何从零开始实现阿克曼ROS小车的运动控制。内容涵盖硬件搭建、STM32底层PID速度与舵机控制、ROS层阿克曼运动学模型解析,以及上下位机通信协议设计。通过手把手的代码示例和调试步骤,帮助机器人爱好者与开发者掌握将高级速度指令转化为小车具体动作的全流程,实现流畅的阿克曼转向控制。

weixin_29193259的博客 200

java.lang.thread_进程&线程(&java.lang.Thread)详解

一.进程与线程进程我们在进行操作电脑的时候,通常会打开浏览器,通讯工具等应用程序,这个时候CPU通过作业调度在内存中就会分配一些空间让它们处于宏观上的运行状态(处于可以被CPU执行的状态),而这部分空间资源就可以说是相应的进程占据的,很显然运行不同的程序需要不同的进程,在内存中也为它们分配独立,无共享的区域。静态描述进程的是PCB快(数据结构集),它是系统感知进程存在的唯一实体,通常包含进程名(或...

weixin_28761343的博客 893

GD32H7 SPI驱动实战:手把手教你用SPI3连接外部Flash(W25Q128)并实现读写

本文详细介绍了基于GD32H7系列MCU的SPI3接口驱动W25Q128外部Flash的全流程开发指南。从硬件设计、引脚配置到SPI3外设深度配置,再到底层通信函数实现和高级功能优化,提供了完整的解决方案。特别针对高速读取、DMA传输和信号完整性等关键环节进行了优化,确保系统在-40℃~85℃范围内稳定工作。

weixin_28729205的博客 384

多线程简单学习及案例解析

多线程 1.1进程 进程:正在运行的程序 是系统进行资源分配和调用的独立单位 每一个进程都有它自己的内存空间和系统资源 1.2线程 线程:是进程中的单个顺序控制流,是一条执行路径 单线程:一个进程如果只有一条执行路径,则称为单线程程序 多线程:一个进程如果有多条执行路径,则称为多线程程序 1.3多线程的实现方式 方式1:继承thread类 定义一个类MyThread继承Thread类 在MyThread类中重写run()方法 创建My

weixin_42596719的博客 286

YOLOv13改进策略【损失函数篇】| 2024 引进Focaler-IoU损失函数 加强边界框回归 (Focaler-DIoU、Focaler-GIoU、Focaler-CIoU)

本文记录的是改进YOLOv13的损失函数,将其替换成。现有研究通过利用边界框之间的几何关系来提高回归性能,但忽略了困难样本和简单样本分布对边界框回归的影响。不同检测任务中困难样本和简单样本的分布不同,对于简单样本占主导的检测任务,关注简单样本的边界框回归有助于提高检测性能;对于困难样本比例较高的检测任务,需要关注困难样本的边界框回归。,提高检测器在不同检测任务中的性能。实现的。

Limiiiing的博客 870

第32篇:Vibe Coding时代:LangGraph + Redis 任务状态持久化实战,解决服务重启后任务状态丢失问题

LangGraph + Redis任务状态持久化方案 本文针对Agent任务状态丢失问题,提出基于Redis的持久化解决方案。当服务重启时,传统内存存储方式会导致任务状态丢失,影响用户体验和运维排查。 核心方案 使用Redis Hash存储任务状态,key格式为agent:task:{task_id} 设计完整状态字段包括task_id、status、progress等关键信息 实现task_store模块提供CRUD操作接口 在Agent执行各节点更新Redis中的任务状态 技术实现 通过Celery执行

sundong_81的博客 44

Java多线程编程详解

一:理解多线程多线程是这样一种机制,它允许在程序中并发执行多个指令流,每个指令流都称为一个线程,彼此间互相独立。 线程又称为轻量级进程,它和进程一样拥有独立的执行控制,由操作系统负责调度,区别在于线程没有独立的存储空间,而是和所属进程中的其它线程共享一个存储空间,这使得线程间的通信远较进程简单。多个线程的执行是并发的,也就是在逻辑上“同时”,而不管是否是物理上的“同时”。如果系统只有一个C

小人物的专栏 *^_^* 898

手把手教你学pcie--内存管理和保护机制(一):MPU与其他内存管理和保护机制详解

MPU(Memory Protection Unit)是一种专门用于 ​。,这些机制通常协同工作,形成多层防御体系,兼顾安全性、性能和灵活性。

MHD0815的博客 280

SoftPhone(eXosip)学习笔记系列之事件侦听

上篇完成了一个完整的用户注册过程,接下来要做就是事件侦听,包括侦听用户呼叫等,这里显然要开辟一个新线程,具体代码不在赘述,我只记下思路,因为网上这类东西几乎没有。while(.....){        eXosip_event_t *event;        event = eXosip_event_wait(0, 50);        eXosip_lock ();        eXos...

cissco 713

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

SoftPhone(eXosip)学习笔记系列之用户注册

用户注册:注册类整理int CSipRegister::Register(ConfigMessage CfgMsg,UserMessage UsMsg){ int i; int retVal; osip_message_t *reg = NULL;  i = eXosip_init (); if (i != 0)  {  TRACE0("--Couldn't initialize eXosip!\...

cissco 477

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

用osip2+eXosip2+ortp+mediastreamer实现的linux简易软电话源代码(可实现通话)

编译命令:  gcc -losip2 -leXosip2 -lmediastreamer -lpthread -o my_exosip_phone my_exosip_phone.c my_exosip_phone.c如下:  #include   #include   #include   #include   #include   #include   #include

zqf_office的专栏 2399

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

soft phone develop

<br />一 服务器端软件<br />1. Asterisk:Linux系统下开源的IPPBX,功能强大稳定,主要用c语言开发。配置稍麻烦。 http://www.asterisk.org/<br />2. Vocal:Linux系统下开源的SIP服务器端。可以作为IPPBX也可以作为运营系统。很多voip虚拟运营商都用这个作为自己的运营系统。提供BS结构的管理界面。http://www.vovida.org/<br />3. YATE:跨平台(Linux,Windows)的开源SIP服务器端。在wind

sunvalley80的专栏 566

Voip/Sip开源项目的一些简单描述

http://blog.youkuaiyun.com/fancyaphy/archive/2006/03/09/619411.aspx    Voip/Sip开源项目的一些简单描述 收藏 Voip/Sip开源项目的一些简单描述 RESIPROCATE: http://www.sipfoundry.org/reSIProcate/ reSIProcate is a high performance, objec

zxg519的专栏 755

Open Source SIP Stack and Media Links

Recommended Open Source Portability Framework http://www.pjsip.org/links.htm If you're looking forthe base portability/framework library for building your application,then I can recommend the ...

管子(zero)的杂乱空间 197

Java中Thread详解(一篇就够了)

前言 操作系统中,一个进程往往代表着一个应用程序实例,而线程是进程中轻量级的调度单元,也可以看作是轻量级的进程,可以共享进程资源。下面简单介绍在操作系统中线程通用实现方式。接下来内容主要对线程模型进行简单介绍,然后对Java线程实现Thread类进行了解。 线程模型 暂且抛开Java线程,先说明一下在操作系统中,线程通用的几种实现方式。实现线程主要有三种方式。 内核线程模型 使用内核线程实现的方......

starsray的博客 3万+

Java中java.lang.Thread类分析

一、线程的状态 线程从创建到最终的消亡,要经历若干个状态。一般来说,线程包括以下这几个状态:创建(new)、就绪(runnable)、运行(running)、阻塞(blocked)、waiting、timed_waiting、终止(terminated)。 当需要新起一个线程来执行某个子任务时,就创建了一个线程。但是线程创建之后,不会立即进入就绪状态,因为线程的运行需...

IT从业者,生活精致一点,工作认真一点! 1184

Java.lang.Thread类和Java的主线程

◆Java程序启动时,一个线程立即随之启动,通常称之为程序的。◆必须最后完成执行,因为它执行各种关闭动作。一.Java.lang.Thread类。使用Thread类的方法获取主线程信息。◆main()方法即为主线程入口。今日总结到此结束,拜拜!◆产生其他子线程的线程。

2401_85520405的博客 596

Java基础之——Java 线程

Java 线程 1、创建线程类(方法一) Java使用 java.lang.Thread 类代表线程,所有的线程对象都必须是 Thread 类或其子类的实例。每个线程的作用是完成一定的任务,实际上就是执行一段程序流即一段顺序执行的代码。Java 使用线程执行体来代表这段程序流。 Java 中通过继承 Thread 类来创建并启动多线程的步骤如下: 定义 Thread 类的子类,并重写该类的 run() 方法,该 run() 方法的方法体就代表了线程需要完成的任务,因此把 run() 方法称为线程执行体。

前尘忆梦的博客 5085

【JVM源码】- java.lang.Thread的start()方法是如何被执行的

start0对应的native方法为主要做了两件事创建线程调用不同系统的底层实现创建线程,在linux操作系统下为传递给的执行函数,最终会执行对象的run()方法调用函数成功后,操作系统创建的线程会被阻塞住启动线程唤醒在函数创建成功的线程最终操作系统线程执行对象的run()方法。

zzzj的博客 1078
上一篇: 仔细触摸Java编程中的“文档”和“包”
下一篇: 【转载】JAVA 开发工具Jcreator使用技巧总结
start_java
博客等级 码龄22年 5粉丝 84原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值