什么叫多线程-Java支持多线程有何意义,java中单线程和多线程是什么意思

  什么叫多线程?Java支持多线程有何意义,java中单线程和多线程是什么意思

  如何解决写爬虫IP受阻的问题?立即使用。

  java多线程详解:

  一、理解多线程

  多线程是一种允许在一个程序中同时执行多个指令流的机制。每个指令流称为一个线程,彼此独立。线程,也叫轻量级进程,和进程一样有独立的执行控制,操作系统负责调度。不同的是,线程没有独立的存储空间,而是与自己进程中的其他线程共享一个存储空间,这使得线程之间的通信比进程简单得多。

  至于具体的java内存模型,既然Java是作为跨平台语言设计的,显然内存管理应该有一个统一的模型。系统中有一个主存储器。Java中的所有变量都存储在主存中,由所有线程共享。每个线程都有自己的工作内存,在主内存中存储一些变量的副本。线程对工作内存中的所有变量进行操作,所以线程之间不能直接访问对方,变量传输需要通过主存来完成。

  多线程的执行是并发的,也就是逻辑上的“同时”,不管是不是物理上的“同时”。如果系统只有一个CPU,那么真正的“同时”是不可能的。多线程和传统单线程在编程上最大的区别在于,每个线程的控制流是相互独立的,这样每个线程之间的代码执行起来是乱序的,会带来线程调度、同步等问题。网络管理bitsCN.com

  二、在Java中实现多线程

  让我们想象一下,为了创建一个新线程,我们需要做些什么。显然,我们必须指明这个线程要执行的代码,这就是我们在Java中实现多线程所需要做的一切!

  作为一种完全面向对象的语言,Java提供了java.lang.Thread类来方便多线程编程。这个类提供了很多方法,方便我们控制自己的线程。

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

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

  公共类TwoThread扩展线程{

  公共无效运行(){

  for(int I=0;i 10i ) {

  System.out.println(“新线程”);

  }

  }

  公共静态void main(String[] args) {

  two thread TT=new two thread();

  TT . start();

  for(int I=0;i 10i ) {

  System.out.println(主线程);

  }

  }

  }这种方法简单明了,符合大家的习惯。但是,它也有一个很大的缺点,就是如果我们的类已经继承了一个类,我们就不能再继承Thread类了。

  方法2:实现Runnable接口。

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

  公共类MyThread实现Runnable {

  int count=1,number

  public MyThread(int num) {

  number=num

  System.out.println(创建线程号);

  }

  公共无效运行(){

  while(true) {

  system . out . println( thread number :count count);

  if( count==6)返回;

  }

  }

  公共静态void main(String args[]) {

  for(int I=0;i5;我)

  新线程(新的MyThread(i 1))。start();

  }

  }使用Runnable接口实现多线程,使我们能够将所有代码包含在一个类中,有利于封装。下面我们一起来研究多线程中的一些问题。

  三、线程的四种状态

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

  2.可执行状态:线程可以执行,尽管它不一定正在执行。CPU可以随时分配给这个线程,从而使它执行。

  3.阻塞状态:线程不会被分配CPU时间,无法执行;它可能被I/O或同步锁阻塞。

  4.死亡状态:正常情况下,run()返回导致线程死亡。调用stop()或destroy()具有相同的效果,但不建议这样做。前者会产生异常,后者会被强制终止,不会释放锁。

  四、线程的优先级

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

  可以调用Thread类的方法getPriority()和setPriority()来访问线程的优先级。线程的优先级在1(MIN_PRIORITY)到10(MAX_PRIORITY)之间,默认值为5(NORM_PRIORITY)。

  五、线程的同步

  由于同一个进程中的多个线程共享同一个存储空间,在带来便利的同时,也带来了严重的访问冲突问题。Java提供了一种特殊的机制来解决这种冲突,有效地防止了同一个数据对象被多个线程同时访问。

  我们只需要为方法提出一个机制,就是synchronized关键字,它包括两种用法:synchronized方法和synchronized块。

  1.synchronized方法:通过在方法声明中添加synchronized关键字来声明一个synchronized方法。Synchronized方法控制对类成员变量的访问:每个类实例对应一个锁,每个synchronized方法必须获得调用该方法的类实例的锁才能执行,否则自己的线程会阻塞。一旦方法被执行,它将独占锁,直到从方法返回,锁才会被释放。之后,被阻塞的线程可以获得锁并重新进入可执行状态。这种机制保证了对于同一时刻的每个类实例,最多只有一个声明为synchronized的成员函数处于可执行状态(因为最多只有一个成员函数可以获取类实例的相应锁),从而有效避免了类成员变量的访问冲突(只要所有可能访问类成员变量的方法都声明为synchronized即可)。

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

  synchronized方法的缺点:如果一个大的方法被声明为synchronized,会大大影响效率。通常,如果thread类的方法run()被声明为synchronized,它将永远无法成功调用该类的任何synchronized方法,因为它在线程的生命周期中一直运行。

  2.synchronized块:synchronized块由synchronized关键字声明。语法如下:

  同步(同步对象){

  //允许访问控制的代码

  } synchronized block是一个代码块,其中的代码必须获得对象syncObject的锁才能执行。具体机理和上面说的一样。由于它可以针对任何代码块,锁定对象可以任意指定,因此具有很高的灵活性。

  以上是java多线程所指的细节。请多关注我们的其他相关文章!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: