java为什么要有线程 线程在java编程中的作用
其实java为什么要有线程的问题并不复杂,但是又很多的朋友都不太了解线程在java编程中的作用,因此呢,今天小编就来为大家分享java为什么要有线程的一些知识,希望可以帮助到大家,下面我们一起来看看这个问题的分析吧!
Java多线程初学者指南(9):为什么要进行数据同步
Java中的变量分为两类局部变量和类变量局部变量是指在方法内定义的变量如在run方法中定义的变量对于这些变量来说并不存在线程之间共享的问题因此它们不需要进行数据同步类变量是在类中定义的变量作用域是整个类这类变量可以被多个线程共享因此我们需要对这类变量进行数据同步
数据同步就是指在同一时间只能由一个线程来访问被同步的类变量当前线程访问完这些变量后其他线程才能继续访问这里说的访问是指有写操作的访问如果所有访问类变量的线程都是读操作一般是不需要数据同步的
那么如果不对共享的类变量进行数据同步会发生什么情况呢?让我们先看看下面的代码会发生什么样的事情
packagetest;publicclassMyThreadextendsThread{publicstaticintn=;publicvoidrun(){intm=n;yield();m++;n=m;}publicstaticvoidmain(String[]args)throwsException{MyThreadmyThread=newMyThread();Threadthreads[]=newThread[ ];for(inti=;i<threads length;i++)threads[i]=newThread(myThread);for(inti=;i<threads length;i++)threads[i] start();for(inti=;i<threads length;i++)threads[i] join();System out println( n=+MyThread n);}}
在执行上面代码的可能结果如下
n=
看到这个结果可能很多读者会感到奇怪这个程序明明是启动了个线程然后每个线程将静态变量n加最后使用join方法使这个线程都运行完后再输出这个n值按正常来讲结果应该是n=可偏偏结果小于
其实产生这种结果的罪魁祸首就是我们经常提到的脏数据而run方法中的yield()语句就是产生脏数据的始作俑者(不加yield语句也可能会产生脏数据但不会这么明显只有将改成更大的数才会经常产生脏数据在本例中调用yield就是为了放大脏数据的效果) yield方法的作用是使线程暂停也就是使调用yield方法的线程暂时放弃CPU资源使CPU有机会来执行其他的线程为了说明这个程序如何产生脏数据我们假设只创建了两个线程 thread和thread由于先调用了thread的start方法因此 thread的run方法一般会先运行当thread的run方法运行到第一行(int m= n)时将n的值赋给m当执行到第二行的yield方法后 thread就会暂时停止执行而当thread暂停时 thread获得了CPU资源后开始运行(之前thread一直处于就绪状态)当thread执行到第一行(int m= n)时由于thread在执行到yield时n仍然是因此 thread中的m获得的值也是这样就造成了thread和thread的m获得的都是在它们执行完yield方法后都是从开始加因此无论谁先执行完最后n的值都是只是这个n被thread和thread各赋了一遍值这个过程如下图如示
也许有人会问如果只有n++会产生脏数据吗?答案是肯定的那么n++只是一条语句又如何在执行过程中将CPU交给其他的线程呢?其实这只是表面现象 n++在被Java编译器编译成中间语言(也叫做字节码)后并不是一条语言让我们看看下面的Java代码将会被编译成什么样的Java中间语言
Java源代码
publicvoidrun(){n++;}
被编译后的中间语言代码
publicvoidrun(){ aload_ dup getfield iconst_ iadd putfield return}
大家可以看到在run方法中只有n++一条语句而在编译后却有条中间语言语句我们并不需要知道这些语句的功能是什么只看一下第和行语句在行是getfield根据它的英文含义可知是要得到某个值因为这里只有一个n所以毫无疑问是要得到n的值而在行的iadd也不难猜测是将这个得到的n值加在行的putfield的含义我想大家可能已经猜出来了它负责将这个加后的n再更新回类变量n说到这可能大家还有一个疑惑执行n++时直接将n加不就行了为什么要如此费周折其实这里涉及到一个Java内存模型的问题
Java的内存模型分为主存储区和工作存储区主存储区保存了Java中所有的实例也就是说在我们使用new来建立一个对象后这个对象及它内部的方法变量等都保存在这一区域在MyThread类中的n就保存在这个区域主存储区可以被所有线程共享而工作存储区就是我们前面所讲的线程栈在这个区域里保存了在run方法以及run方法所调用的方法中定义的变量也就是方法变量在线程要修改主存储区中的变量时并不是直接修改这些变量而是将它们先复制到当前线程的工作存储区在修改完后再将这个变量值覆盖主存储区的相应的变量值
lishixinzhi/Article/program/Java/gj/201311/27623为什么要用线程呢在什么时候用到!
呵呵想理解多线程你就得搞清楚什么是并发什么是并行,概念:在单CPU系统中,系统调度在某一时刻只能让一个线程运行,虽然这种调试机制有多种形式(大多数是时间片轮巡为主),但无论如何,要通过不断切换需要运行的线程让其运行的方式就叫并发(concurrent)。而在多CPU系统中,可以让两个以上的线程同时运行,这种可以同时让两个以上线程同时运行的方式叫做并行(parallel)。我也有段时间纠结于这里,无论如何我必须得给你明确一点:在某一个时间点,一个CPU(单)只会运行某一个进程里的单个线程,所以我们经常称之为并发,说道同步机制,其实多线程并未真正实现微观意义上的同步,进程是一个运行单元,线程则是更小的运行单元,简而言之,就是进程细分成多个线程,譬如:一个进程A运行需要1s,它就会切换到进程B,但是实现多线程机制后,进程A细化成10个线程,每个线程只需运行0.1s,当然B线程也一样,这就出现,线程之间的切换时间更短,从宏观上看就出现同步幻象了。所以学习多线程你得真正理解所谓的同步并发,并不是真正的“同步”。当你理解这些的时候,你就初略的感觉什么时候该使用多线程机制,其实你的电脑每个程序都至少有一个主线程,那个管理器中的每一个进程,其实内部包含若干线程,每个时间点都是某个程序进程中的某个线程在运行。这些都是我的理解,还有不懂的请继续提出,我会尽量帮你解答。
java 多线程是什么
线程定义比较抽象,简单的说就是一个代码执行流。许多执行流可以混合在一起由CPU调度。线程是允许各种任务交互执行的方式。
Java的线程在操作系统的实现模式依系统不同而不同,可能是系统级别的进程或线程,但对于程序员来说并没有影响。
任务交互的一个好处是增加程序响应。如一个界面程序执行一段耗时的数据库查询,使用单独的线程可以让界面依然响应用户的其他输入,而单线程只能等待查询结束再处理。
JVM以及操作系统会优先处理优先级别高的线程,但不代表这些线程一定会先完成。设定优先级只能建议系统更快的处理,而不能强制。
另外,在运行时,并没有按照函数分界,而是按照机器码/汇编码分界。也就是说不保证任何一段代码是被完整而不打断的执行的(除非你已经使用同步手段)。正由于如此,各种线程同步的方法应运而生。
线程在java编程中的作用
线程在java编程中的作用可以实现多个任务同时进行。java创建线程的方式最常用的有两种。
1、第一种是创建Thread子类的一个实例并重写run方法,run方法会在调用start()方法之后被执行。例子如下:
publicclassMyThreadextendsThread{
publicvoidrun(){
System.out.println("MyThreadrunning");
}
}
MyThreadmyThread=newMyThread();
myTread.start();
2、第二种编写线程执行代码的方式是新建一个实现了java.lang.Runnable接口的类的实例,实例中的方法可以被线程调用。下面给出例子:
publicclassMyRunnableimplementsRunnable{
publicvoidrun(){
System.out.println("MyRunnablerunning");
}
}
Threadthread=newThread(newMyRunnable());
thread.start();
好了,本文到此结束,如果可以帮助到大家,还望关注本站哦!