线程是java的什么机制 JAVA线程的机制有哪些
大家好,如果您还对线程是java的什么机制不太了解,没有关系,今天就由本站为大家分享线程是java的什么机制的知识,包括JAVA线程的机制有哪些的问题都会给大家分析到,还望可以解决大家的问题,下面我们就开始吧!
java线程是什么
一、操作系统中线程和进程的概念
现在的操作系统是多任务操作系统。多线程是实现多任务的一种方式。
进程是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程中可以启动多个线程。比如在Windows系统中,一个运行的exe就是一个进程。
线程是指进程中的一个执行流程,一个进程中可以运行多个线程。比如java.exe进程中可以运行很多线程。线程总是属于某个进程,进程中的多个线程共享进程的内存。
“同时”执行是人的感觉,在线程之间实际上轮换执行。
二、Java中的线程
在Java中,“线程”指两件不同的事情:
1、java.lang.Thread类的一个实例;
2、线程的执行。
使用java.lang.Thread类或者java.lang.Runnable接口编写代码来定义、实例化和启动新线程。
一个Thread类实例只是一个对象,像Java中的任何其他对象一样,具有变量和方法,生死于堆上。
Java中,每个线程都有一个调用栈,即使不在程序中创建任何新的线程,线程也在后台运行着。
一个Java应用总是从main()方法开始运行,mian()方法运行在一个线程内,它被称为主线程。
一旦创建一个新的线程,就产生一个新的调用栈。
线程总体分两类:用户线程和守候线程。
当所有用户线程执行完毕的时候,JVM自动关闭。但是守候线程却不独立于JVM,守候线程一般是由操作系统或者用户自己创建的
Java线程的概念与原理
一操作系统中线程和进程的概念
现在的操作系统是多任务操作系统多线程是实现多任务的一种方式
进程是指一个内存中运行的应用程序每个进程都有自己独立的一块内存空间一个进程中可以启动多个线程比如在Windows系统中一个运行的exe就是一个进程线程是指进程中的一个执行流程一个进程中可以运行多个线程比如java exe进程中可以运行很多线程线程总是属于某个进程进程中的多个线程共享进程的内存同时执行是人的感觉在线程之间实际上轮换执行
二 Java中的线程
在Java中线程指两件不同的事情
java lang Thread类的一个实例
线程的执行
使用java lang Thread类或者java lang Runnable接口编写代码来定义实例化和启动新线程一个Thread类实例只是一个对象像Java中的任何其他对象一样具有变量和方法生死于堆上 Java中每个线程都有一个调用栈即使不在程序中创建任何新的线程线程也在后台运行着一个Java应用总是从main()方法开始运行 mian()方法运行在一个线程内它被称为主线程一旦创建一个新的线程就产生一个新的调用栈线程总体分两类用户线程和守候线程
当所有用户线程执行完毕的时候 JVM自动关闭但是守候线程却不独立于JVM守候线程一般是由操作系统或者用户自己创建的
———————————MultiT java——————————————————————
class MultiThread
{
public static void main(String[] args)
{
MyThread mt=new MyThread();
//mt setDaemon(true);//设定为后台线程 main进程结束时后台进程也跟着结束
//mt setPriority(Thread MAX_PRIORITY);//设定线程优先级 MAX_PRIORITY为 MIN_PRIORITY为 NORM_PRIORITY为
//设定为最高优先级后程序运行时 mt线程一直运行强制终止时 main线程才运行
//设定为最高优先级的线程无论有无yield();线程总一直运行直到强制终止时 main和mt线程交替运行
mt start();
int index=;
while(true)//显示结果与教程不同
{
if(index++==)
break;
System out println( main:+Thread currentThread() getName());//获取线程名字
}
}
}
class MyThread extends Thread
{
public void run()
{
while(true)
{
System out println(getName());
yield();//允许当前线程停止转去执行其他线程静态方法
//mt进程执行时切换到main进程 main进程执行一段时间后
//切换进程到mt mt执行完获取名字后返回到main进程
}
}
}
//一个长时间处于等待状态的线程也有可能被线程调度器调度从而运行
//打破高优先级线程始终获有运行时间的状态
——————————————————————————————————————
——————————MultiThread java———————————————————————
class MultiThread
{
public static void main(String[] args)
{
MyThread mt=new MyThread();
//new Thread(mt) start();//创建多个同样的线程访问同一个变量index若MyThread采用继承Thread方式则无法共享同一个变量
//new Thread(mt) start();
//new Thread(mt) start();
//new Thread(mt) start();
mt getThread() start();//也可以采用内部类的方式共享访问同一个变量
mt getThread() start();
mt getThread() start();
mt getThread() start();
//mt setDaemon(true);//设定为后台线程 main进程结束时后台进程也跟着结束
//mt setPriority(Thread MAX_PRIORITY);//设定线程优先级 MAX_PRIORITY为 MIN_PRIORITY为 NORM_PRIORITY为
//设定为最高优先级后程序运行时 mt线程一直运行强制终止时 main线程才运行
//设定为最高优先级的线程无论有无yield();线程总一直运行直到强制终止时 main和mt线程交替运行
//mt start();
int index=;
while(true)//显示结果与教程不同
{
// if(index++==)
// break;
System out println( main:+Thread currentThread() getName());//获取线程名字
}
}
}
class MyThread//implements Runnable//extends Thread//使用外部类的方式
//使用内部类完成使用Runnable接口才能完成的两个功能 a创建多个线程 b访问同一个变量
{
int index=;
private class InnerThread extends Thread//不想让外部访问其实现方法加上private
{
public void run()
{
while(true)
{
System out println(Thread currentThread() getName()+:+index++);
}
}
}
Thread getThread()
{
return new InnerThread();
}
/*
public void run()
{
while(true)
{
System out println(Thread currentThread() getName()+:+index++);
//yield();//允许当前线程停止转去执行其他线程静态方法
//mt进程执行时切换到main进程 main进程执行一段时间后
//切换进程到mt mt执行完获取名字后返回到main进程
}
}
*/
}
//一个长时间处于等待状态的线程也有可能被线程调度器调度从而运行
//打破高优先级线程始终获有运行时间的状态
//如果不需要修改Thread类的除了run方法外的其他方法选用implements Runnable
———————————————————————————————————————
———————————TicketsSystem java———————————————————
//多线程实现火车票的售票系统用同步块或著同步方法
class TicketsSystem
{
public static void main(String[] args)//运行结果与教程中不同不完全顺序每次运行顺序都不完全一样
{
SellThread st=new SellThread();//创建四个线程访问同一变量tickets
//错 SellThread st=new SellThread();//若采用创建四个对象的方式则每个对象中都有张票
new Thread(st) start();//b为false用的同步方法|//同步方法与同步块共用中显示的是只调用了同步块而同步方法未被调用
//b为true用的同步块|//原因启动第一个线程后 CPU时间片没有到期线程没有立即运行接着执行b=true
//|//解决办法启动第一个线程后执行一个睡眠时间让CPU时间片到期
try
{
Thread sleep();
}
catch(Exception e)
{
e printStackTrace();
}
st b=true;
new Thread(st) start();
//new Thread(st) start();
//new Thread(st) start();
}
}
class SellThread implements Runnable//程序有点小问题当剩下最后一张票时四个线程都运行可能会出现票数为(系统长时间运行时)
//可加上一个静态方法sleep();它会抛出异常
{
int tickets=;
//Object obj=new Object();//也可以声明一个Thread对象
Thread th=new Thread();
boolean b=false;
public void run()
{
if(b==false)
{
while(true)
sell();
}
else
{
while(true)
{//同步方法利用的是this所代表的对象的锁
synchronized(this)//采用同步后显示正确此方法两步声明Thread对象用synchronized把原方法括起来
{//这里换th为this
///*
if(tickets>)
{
try
{
Thread sleep();
}
catch(Exception e)
{
e printStackTrace();
}
System out println( th+Thread currentThread() getName()+ sell tickets:+tickets);
tickets;
}
//*/
}
}
}
}
public synchronized void sell()//每个class也有一个锁是这个class所对应的class对象的锁(监视器)
{
if(tickets>)
{
try
{
Thread sleep();
}
catch(Exception e)
{
e printStackTrace();
}
System out println( sell+Thread currentThread() getName()+ sell tickets:+tickets);
tickets;
}
}
}
————————————————————————————————————————
———————————TestWN java————————————————————
class Test
{
public static void main(String[] args)
{
Queue q=new Queue();
Producer p=new Producer(q);
Consumer c=new Consumer(q);
p start();
c start();
}
}
class Producer extends Thread
{
Queue q;
Producer(Queue q)
{
this q=q;
}
public void run()
{
for(int i=;i<;i++)
{
q put(i);
System out println( Producer put:+i);
}
}
}
class Consumer extends Thread
{
Queue q;
Consumer(Queue q)
{
this q=q;
}
public void run()
{
while(true)
{
System out println( Consumer get:+q get());
}
}
}
class Queue//wait notify方法必须用在同步方法中要加上关键字synchronized
{
int value;
boolean bFull=false;
public synchronized void put(int i)
{
if(!bFull)
{
value=i;
bFull=true;
notify();
}
try
{
wait();
}
catch(Exception e)
{
e printStackTrace();
}
}
public synchronized int get()
{
if(!bFull)
{
try
{
wait();
}
catch(Exception e)
{
e printStackTrace();
}
}
bFull=false;
notify();
return value;
}
}
————————————————————————————————————
————————————TestThread java———————————————————————
class TestThread
{
public static void main(String[] args)
{
Thread t=new Thread();
t start();
int index=;
while(true)
{
if(index++==)
{
t stopThread();
t interrupt();//让线程终止
break;
}
System out println(Thread currentThread() getName());
}
System out println( main() exit);
}
}
class Thread extends Thread
{
private boolean bStop=false;
public synchronized void run()
{
while(!bStop)
{
try
{
wait();//加入wait后 main线程结束时程序还未终止原因是Thread的线程调用wait方法进入对象的等待队列中需要notify方法将它唤醒
}
catch(Exception e)
{
//e printStackTrace();
if(bStop)
return;
}
System out println(getName());
}
}
public void stopThread()
{
bStop=true;
}
}
lishixinzhi/Article/program/Java/gj/201311/27407JAVA线程的机制有哪些
Java的线程机制摘要:多线程机制是Java的重要技术,阐述了线程和进程的差别;Java中线程4个状态之间的转换;并结合例子说明了两种创建线程的方法。线程是指程序中能顺序执行的一个序列。一个线程只有一个入口点�但可能有几个出口点�不过,每个时刻的执行点总是只有一个。线程是不能独立运行的程序,而只是某个整体程序内部的一个顺序执行流。多线程是Java的一个重要特点。如果一个程序是单线程的,那么,任何时刻都只有一个执行点。这种单线程执行方法使系统运行效率低,而且,由于必须依靠中断来处理输入/输出。所以,当出现频繁输入/输出或者有优先级较低的中断请求时,实时性就变得很差。多线程系统可以避免这个缺点。所谓多线程,就是通过系统的调度使几个具有不同功能的程序流即线程同时并行地运行。在单处理器计算机系统中,实际上是不可能使多个线程真正并行运行的,而要通过系统用极短的时间、极快的速度对多个线程进行切换,宏观上形成多个线程并发执行的效果。1线程和进程机制上的差别线程和进程很相象,它们都是程序的一个顺序执行序列,但两者又有区别。进程是一个实体,每个进程有自己独立的状态,并有自己的专用数据段,创建进程时,必须建立和复制其专用数据段,线程则互相共享数据段。同一个程序中的所有线程只有一个数据段,所以,创建线程时不必重新建立和复制数据段。由于数据段建立和复制这方面的差异,使线程的建立和线程间的切换速度大大优于进程,另一方面,线程又具备进程的大多数优点。假设银行系统办理存款和取款手续,将帐本看成数据段。如果按进程这种机制,那么,当储户去存/取款时,银行应先把帐本复制一遍,为储户建立一个独立的帐本再结算。如果按线程机制,那么,银行里所有的出纳员都用同一个帐本,储户来办存/取款时,也从这个帐本直接结算。用线程机制省去了数据段复制这一步显然是线程独具的特点。由于多个线程共享一个数据段,所以,也出现了数据访问过程的互斥和同步问题,这使系统管理功能变得相对复杂。总的来说,一个多线程系统在提高系统的输入/输出速度、有效利用系统资源、改善计算机通信功能以及发挥多处理器硬件功能方面显示了很大优势。因此,一些最新的操作系统如Windows95、Windows98、Windows NT等都提供了对多线程的支持。但是,在多线程操作系统下设计多线程的程序仍然是一个比较复杂和困难的工作。由于需要解决对数据段的共享,所以,原则上应该从程序设计角度采用加锁和释放措施,稍有不慎,便会使系统产生管理上的混乱。而Java从语言一级提供对多线程的支持,这样,可由语言和运行系统联合提供对共享数据段的管理功能和同步机制,使得多线程并行程序设计相对比较容易。2 Java线程的生命周期每个线程都是和生命周期相联系的,一个生命周期含有多个状态,这些状态间可以互相转化。 Java的线程的生命周期可以分为4个状态;创建(new)状态;可运行(runnable)状态;不执行(notrunnable)状态;消亡(dead)状态。创建状态是指创建一个线程对应的对象的过程,Java系统中,些对象都是从Java.lang包内一个称为Thread的类用关键字new创建的。刚创建的线程不能执行,必须向系统进行注册、分配必要的资源后才能进入可运行状态,这个步骤是由start操作完成的,而处于可运行状态的线程也未必一定处于运行中,它有可能由于外部的I/O请求而处于不运行状态。进入消亡状态后,此线程就不再存在了。一个线程创建之后,总是处于其生命周期的4个状态之一中,线程的状态表明此线程当前正在进行的活动,而线程的状态是可以通过程序来进行控制的,就是说,可以对线程进行操作来改变状态。这些操作包括启动(start)、终止(stop)、睡眠(sleep)、挂起(suspend)、恢复(resume)、等待(wait)和通知(notify)。每一个操作都对应了一个方法�这些方法是由软件包Java.lang提供的。通过各种操作,线程的4个状态之间可按图1所示进行转换。 2.1创建(new)状态如果创建了一个线程而没有启动它,那么,此线程就处于创建状态。比如,下述语句执行以后,使系统有了一个处于创建状态的线程myThread:� Thread myThread=new MyThreadClass();其中,MyThreadClass()是Thread的子类,而Thread是由Java系统的Java.lang软件包提供的。处于创建状态的线程还没有获得应有的资源,所以,这是一个空的线程,线程只有通过启动后,系统才会为它分配资源。对处于创建状态的线程可以进行两种操作:一是启动(start)操作,使其进入可运行状态;二是终止(stop)操作,使其进入消亡状态。如果进入到消亡状态,那么,此后这个线程就不能进入其它状态,也就是说,它不复存在了。 start方法是对应启动操作的方法,其具体功能是为线程分配必要的系统资源,将线程设置为可运行状态,从而可以使系统调度这个线程。 2.2可运行(runnable)状态如果对一个处于创建状态的线程进行启动操作,则此线程便进入可运行状态。比如,用下列语句� myThread.start();��则使线程myThread进入可运行状态。上述语句实质上是调用了线程体即run()方法,注意,run()方法包含在myThread线程中,也就是先由java.lang包的Thread类将run()方法传递给子类MyThreadClass(),再通过创建线程由子类MyThreadClass,传递给线程myThread。线程处于可运行状态只说明它具备了运行条件,但可运行状态并不一定是运行状态,因为在单处理器系统中运行多线程程序,实际上在一个时间点只有一个线程在运行,而系统中往往有多个线程同时处于可运行状态,系统通过快速切换和调度使所有可运行线程共享处理器,造成宏观上的多线程并发运行。可见,一个线程是否处于运行状,除了必须处于可运行状态外,还取决于系统的调度。在可运行状态可以进行多种操作,最通常的是从run()方法正常退出而使线程结束,进入消亡状态。此,还可以有如下操作�挂起操作,通过调用suspend方法来实现;睡眠操作,通过调用sleep方法来实现;等待操作,通过调用wait方法来实现;退让操作,通过调用yield方法来实现;终止操作,通过调用stop方法来实现。前面三种操作都会使一个处于可运行状态的线程进入不可运行状态。比如,仍以myThread线程为例,当其处于可运行状态后,再用如下语句� myThread.sleep(5000);则调用sleep方法使myThread线程睡眠5s(5000ms)。这5s内,此线程不能被系统调度运行,只有过5s后,myThread线程才会醒来并自动回到可运行状态。如果一个线程被执行挂起操作而转到不可运行状态,则必须通过调用恢复(resume)操作,才能使这个线程再回到可运行状态。退让操作是使某个线程把CPU控制权提前转交给同级优先权的其他线程。对可运行状态的线程也可以通过调用stop方法使其进入消亡状态。 2.3不可运行(not runnable)状态不可运行状态都是由可运行状态转变来的。一个处于可运行状态的线程,如果遇到挂起(suspend)操作、睡眠(sleep)操作或者等待(wait)操作,就会进入不可运行状态。另外,如果一个线程是和I/O操作有关的,那么,在执行I/O指令时,由于外设速度远远低于处理器速度而使线程受到阻,从而进入不可运行状态,只有外设完成输入/输出之后,才会自动回到可运行状态。线程进入不可运行状态后,还可以再回到可运行状态,通常有三种途径使其恢复到可运行状态。一是自动恢复。通过睡眠(sleep)操作进入不可运行状态的线程会在过了指定睡眠时间以后自动恢复到可运行状态,由于I/O阻塞而进入不可运行状态的线程在外设完成I/O操作后,自动恢复到可运行状态。二是用恢复(resume)方法使其恢复。如果一个线程由于挂起(suspend)操作而从可运行状态进入不可运行状态,那么,必须用恢复(resume)操作使其再恢复到可运行状态。三是用通知(notify或notifyAll)方法使其恢复。如果一个处于可运行状态的线程由于等待(wait)操作而转入不可运行状态,那么,必须通过调用notify方法或notifyAll方法才能使其恢复到可运行状态,采用等待操作往往是由于线程需要等待某个条件变量,当获得此条件变量后,便可由notify或ontifyAll方法使线程恢复到可运行状态。恢复到可运行状态的每一种途径都是有针对性的,不能交叉。比如,对由于阻塞而进入不可运行状态的线程采用恢复操作将是无效的。在不可运行状态,也可由终止(stop)操作使其进入消亡状态。 2.4消亡(dead)状态一个线程可以由其他任何一个状态通过终止(stop)操作而进入消亡状态。线程一旦进入消亡状态,那它就不再存在了,所以也不可能再转到其它状态。通常,在一个应用程序运行时,如果通过其它外部命令终止当前应用程序,那么就会调用(stop)方法终止线程。但是,最正常、最常见的途径是由于线程在可运行状态正常完成自身的任务而″寿终正寝″,从而进入消亡状态,这个完成任务的动作是由run方法实现的。3 Java线程的两种创建途径一种途径是通过对Thread的继承来派生一个子类,再由此子类生成一个对象来实现线程的创建,这是比较简单直接的办法。Thread类包含在系统API提供的8个软件包之一Java.lang中,Thread类中包含了很多与线程有关的方,其中,一个名为run的方法就是用来实现线程行为的。比如:�1 import java.lang.*�//引用lang包2 class Mango exteds Thread{3 public void run(){4......5�}6�}上述程序段中,第1行语句引用软件包lang,这样做是为了给编译器一个信息,从而使后面程序中有关lang包中的方法可直接用方法名,而不必带前缀“Java.lang”。第2行语句是从lang包Thread派生一个子类Mango,而这个子类中提供了run方法的实现,这样,运行时,将由子类Mango的 run方法置换父类Thread的run方法。不过这一步还没有创建线,必须由子类生成一个对象,并且进行启动操作,这样才能得到一个处于可运行状态的线程。生成对象其实就是完成线程的创建,而启动是对已创建的线程进行操作。具体语句如下:� Mango t=new Mango();� t.start();�上面先用关键字new使线程进入创建状态,又调用start()方法使线程进入可运行状态。注意,start()方法是由Thread继承给子类Mango、然后又在生成对象时由对象t从类Mango得到的。另一种途径是通过一个类去继承接口runnable来实现线程的创建�而这个类必须提供runnable接口中定义的方法run()的实现。runnable是Java.lang包中的一个接口,在runnable接口中,只定义了一个抽象方法run()。所以,如用这种途径来创建线程,则应先由一个类连接接口runnable,并且提供run()方法的实现。比如,下面的程序段实现了与接口的连接。1 public class xyz implements Runnable{2 int i;�3 public voed run(){4 while(true){�5 System.out.println("Hello"+i++);6�}7�}8�}然后再创建一个线程� runnable r=new xyz();� Thread t=new Thread(r);这种途径创建线程比第一种途径灵活。当一个类既需要继承一个父类又要由此创建一个线程时,由于Java不支持多重继承,这样,用第一种途径将行不通,因为,按此思路创建线程也是以继承的方法实现的。于是,就需要一个类既继承Thread类,又继承另一个父类。但用接口方法却能实现这个目标。4线程的启动和终止 Thread的start()方法对应于启动操作,它完成两方面的功能:一方面是为线程分配必要的资源,使线程处于可运行状态,另一方面是调用线程的run()方法置换Thread的中run()方法或者置换runnable中的run()方法来运行线程。使用start()方法的语句很简单,即: ThreadName.start();下面的程序段先创建并启动线程myThread,然后使用sleep()方法让其睡眠20000ms即20s,使其处于不可运行状态,过20s后,线程又自动恢复到可运行状态。 Thread MyThread=new MyThreadClass(); MyThread.start();�� try{� MyThread.sleep(20000);�} catch(InterrujptedException e){}
OK,本文到此结束,希望对大家有所帮助。