导航:首页 > 编程语言 > java绿色线程

java绿色线程

发布时间:2022-07-04 16:04:44

A. 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,守候线程一般是由操作系统或者用户自己创建的

B. java多线程,对象锁是什么概念

java线程:

1.线程中一些基本术语和概念

1.1线程的几个状态
初始化状态
就绪状态
运行状态
阻塞状态
终止状态
1.2 Daemon线程
Daemon线程区别一般线程之处是:主程序一旦结束,Daemon线程就会结束。
1.3锁的定义
为了协调多个并发运行的线程使用共享资源才引入了锁的概念。
1.4死锁
任何多线程应用程序都有死锁风险。当一组线程中的每一个都在等待一个只
有该组中另一个线程才能引起的事件时,我们就说这组线程死锁了。换一个说法
就是一组线程中的每一个成员都在等待别的成员占有的资源时候,就可以说这组
线程进入了死锁。死锁的最简单情形是:线程 A 持有对象 X 的独占锁,并且
在等待对象 Y 的锁,而线程 B 持有对象 Y 的独占锁,却在等待对象 X 的锁。
除非有某种方法来打破对锁的等待(Java 锁定不支持这种方法),否则死锁的线
程将永远等下去。

1.5.Java对象关于锁的几个方法
1.5.1 wait方法
wait方法是java根对象Object含有的方法,表示等待获取某个锁。在wait方法进入前,会释放相应的锁,在wait方法返回时,会再次获得某个锁。
如果wait()方法不带有参数,那只有当持有该对象锁的其他线程调用了notify或者notifyAll方法,才有可能再次获得该对象的锁。
如果wait()方法带有参数,比如:wait(10),那当持有该对象锁的其他线程调用了notify或者notifyAll方法,或者指定时间已经过去了,才有可能再次获得该对象的锁。
参考 thread.lock.SleepAndWait
1.5.2 notify/notifyAll方法
这里我就不再说明了。哈哈,偷点懒。
1.5.3 yield方法
yield()会自动放弃CPU,有时比sleep更能提升性能。
1.6锁对象(实例方法的锁)
在同步代码块中使用锁的时候,担当锁的对象可以是这个代码所在对象本身或者一个单独的对象担任,但是一定要确保锁对象不能为空。如果对一个null对象加锁,会产生异常的。原则上不要选择一个可能在锁的作用域中会改变值的实例变量作为锁对象。
锁对象,一种是对象自己担任,一种是定义一个普通的对象作为private property来担任,另外一种是建立一个新的类,然后用该类的实例来担任。
参考 :
thread.lock.UseSelfAsLock,使用对象自己做锁对象
thread.lock.UseObjAsLock 使用一个实例对象作锁对象
thread.lock.UseAFinalObjAsLock使用常量对象作为一个锁对象
1.7类锁
实例方法存在同步的问题,同样,类方法也存在需要同步的情形。一般类方法的类锁是一个static object来担任的。当然也可以采用类本身的类对象来作为类锁。
一个类的实例方法可以获得该类实例锁,还可以尝试去访问类方法,包含类同步方法,去获得类锁。
一个类的类方法,可以尝试获得类锁,但是不可以尝试直接获得实例锁。需要先生成一个实例,然后在申请获得这个实例的实例锁。
参考
thread.lock.UseStaticObjAsStaticLock 使用类的属性对象作为类锁。
thread.lock.UseClassAsStaticLock使用类的类对象作为类锁

1.8.线程安全方法与线程不安全方法
如果一个对象的所有的public方法都是同步方法,也就是说是public方法是线程安全的,那该对象的private方法,在不考虑继承的情况下,可以设置为不是线程安全的方法。
参考 thread.lock.SynMethrodAndNotSynMethrod

1.9类锁和实例锁混合使用
在实例方法中混合使用类锁和实例锁;可以根据前面说的那样使用实例锁和类锁。
在类方法中混合使用类锁和实例锁,可以根据前面说的那样使用类锁,为了使用实例锁,先得生成一个实例,然后实例锁。
参考 thread.lock.StaticLockAndObjLock
1.10锁的粒度问题。
为了解决对象锁的粒度过粗,会导死锁出现的可能性加大,锁的粒度过细,会程序开发维护的工作加大。对于锁的粒度大小,这完全要根据实际开发需要来考虑,很难有一个统一的标准。

1.11.读写锁
一个读写锁支持多个线程同时访问一个对象,但是在同一时刻只有一个线程可以修改此对象,并且在访问进行时不能修改。
有2种调度策略,一种是读锁优先,另外就是写锁优先。
参考 thread.lock.ReadWriteLock
1.12 volatile
在Java中设置变量值的操作,除了long和double类型的变量外都是原子操作,也就是说,对于变量值的简单读写操作没有必要进行同步。这在JVM 1.2之前,Java的内存模型实现总是从主存读取变量,是不需要进行特别的注意的。而随着JVM的成熟和优化,现在在多线程环境下volatile关键字的使用变得非常重要。在当前的Java内存模型下,线程可以把变量保存在本地内存(比如机器的寄存器)中,而不是直接在主存中进行读写。这就可能造成一个线程在主存中修改了一个变量的值,而另外一个线程还继续使用它在寄存器中的变量值的拷贝,造成数据的不一致。要解决这个问题,只需要像在本程序中的这样,把该变量声明为volatile(不稳定的)即可,这就指示JVM,这个变量是不稳定的,每次使用它都到主存中进行读取。一般说来,多任务环境下各任务间共享的标志都应该加volatile修饰。

2.线程之间的通讯
在其他语言中,线程之间可以通过消息队列,共享内存,管道等方式来实现
线程之间的通讯,但是java中可以不采用这样方式,关注的是线程之间的同步。
只要保证相关方法运行的线程安全,信息共享是自然就可以显现了。
2.1屏障
屏障就是这样的一个等待点: 一组线程在这一点被同步,这些线程合并各自的结果或者运行到整体任务的下一阶段。
参考:
thread.lock. BarrierUseExample
thread.lock.Barrier
2.2.锁工具类
提供对线程锁的获取,释放功能。展示了锁的获取释放过程。可以作为一个工具类来使用。
参考:thread.lock. BusyFlag

2.3.条件变量
条件变量是POSIX线程模型提供的一种同步类型,和java中的等待通知机制类似。
虽然java中已经有了等待通知机制,但是为了减少在notify/notifyAll方法中
线程调度的开销,把一些不需要激活的线程屏蔽出去,引入了条件变量。
Java中2个(多个)条件变量可以是同一个互斥体(锁对象)。
参考:thread.lock.CondVar 条件变量类
常见的应用情形:
一个锁控制多个信号通道(例如:多个变量),虽然可以采用简单java等待通知机制,但是线程调度效率不高,而且线程可读性也不是太好,这时候可以采用创建一个锁对象(BusyFlag实例),同时使用这个BusyFlag实例来创建多个条件变量(CondVar 实例)。
经常使用到CondVar类的地方是缓冲区管理,比如:管道操作之类的。先创建一个BusyFlag实例,然后创建CondVar 实例,用这个条件变量描述缓冲区是否为空,另外创建CondVar 实例作条件变量述缓冲区是否满。
现实中,马路的红绿灯,就可以采用条件变量来描述。

3. Java线程调度
3.1 Java优先级
java的优先级别共有10种,加上虚拟机自己使用的优先级别=0这种,总共11种。
大多数情况来说,java线程的优先级设置越高(最高=10),那线程越优先运行。
3.2. 绿色线程
线程运行在虚拟机内,操作系统根本不知道这类线程的存在。
线程是由虚拟机调度的。
3.3 本地线程
线程是由运行虚拟机的操作系统完成的。
3.4 Windows本地线程
操作系统,完全能够看得到虚拟机内的每一个线程,同时虚拟机的线程和操作系统的线程是一一对应的。Java的线程调度室由操作系统底层线程决定的。
在win32平台下,windows线程只有6个优先级别。和java线程优先级别对应如下:
Java线程优先级 Windows 95/nt/2000线程优先级
0 THREAD_ PRIORITY_IDLE
1(Thread.MIN_PRIORITY) THREAD_ PRIORITY_LOWEST
2 THREAD_ PRIORITY_LOWEST
3 THREAD_ PRIORITY_BELOW_NORMAL
4 THREAD_ PRIORITY_BELOW_NORMAL
5 (Thread.NORM_PRIORITY) THREAD_ PRIORITY _NORMAL
6 THREAD_ PRIORITY _ABOVE_NORMAL
7 THREAD_ PRIORITY _ABOVE_NORMA
8 THREAD_ PRIORITY _HIGHEST
9 THREAD_ PRIORITY _HIGHEST
10 (Thread.MAX_PRIORITY) THREAD_ PRIORITY _CRITICAL

3.5线程优先级倒置与继承
如果一个线程持有锁(假设该线程名字=ThreadA,优先级别=5),另外一个线程(假设该线程名字=ThreadB,优先级别=7),现在该线程(ThreadA)处于运行状态,但是线程ThreadB申请需要持有ThreadA所获得的锁,这时候,为了避免死锁,线程A提高其运行的优先级别(提高到ThreadB的优先级别=7),而线程ThreadB为了等待获得锁,降低线程优先级别(降低到ThreadA原来的优先级别=5).
上述的这种情况,对于ThreadA,继承了ThreadB的优先级别,这成为优先级别的继承;对于ThreadB暂时降低了优先级别,成为优先级别的倒置。
当然,一旦线程ThreadA持有的锁释放了,其优先级别也会回到原来的优先级别(优先级别=5)。线程ThreadB获得了相应的锁,那优先级别也会恢复到与原来的值(优先级别=7)。

3.6循环调度
具有同样优先级的线程相互抢占成为循环调度。

4.线程池
创建一个线程也是需要一定代价的,为了降低这个代价,采用了和普通对象池的思想建立线程池,以供系统使用。
线程消耗包括内存和其它系统资源在内的大量资源。除了 Thread 对象所需的内存之外,每个线程都需要两个可能很大的执行调用堆栈。除此以外,JVM 可能会为每个 Java 线程创建一个本机线程,这些本机线程将消耗额外的系统资源。最后,虽然线程之间切换的调度开销很小,但如果有很多线程,环境切换也可能严重地影响程序的性能。
使用线程池的方式是,先建立对象池,然后申请使用线程,程序线程运行,运行完毕,把线程返回线程池。
使用线程池的风险:同步错误和死锁,与池有关的死锁、资源不足和线程泄漏。
大家有空可以研究一下tomcat的线程池实现原理思想。
实际上是tomcat已经在从线程池的使用线程时候加上了事件处理机制。
个人认为,线程池之类的实现,一般不要自己实现,因为自己实现主要是稳定性等方面可能作的不够好。
可以参考 apache的jakarta-tomcat-5.5.6的相关代码,具体是:
jakarta-tomcat-connectors\util\java\org\apache\tomcat\util\threads的相关代码

5工作队列
使用工作队列的好处是不象直接使用线程池那样,当线城池中没有线程可以使用的时
候,使用者需要处于等待状态,不能进行其他任务的处理。
工作队列的工作原理是:
采用后台线程处理方式,客户端把任务提交给工作队列,工作队列有一组内部可以工作线程,这些工作线程从工作队列中取出任务运行,一个任务完成后,就从队列获取下一个任务进行处理。当工作队列中没有任务可以处理时候,工作线程就处于等待状态,直到获得新的任务时候,才进行新的处理。

C. 请问如何用JAVA多线程写一个红黄绿依次亮的交通灯程序

import java.awt.*;
import java.awt.event.*;

public class JiaoTong extends Frame {
boolean redStatus=false,greenStatus=false,yellowStatus=false;
int j=0;
public void paint(Graphics g) {
Color c=g.getColor();
if(redStatus==true)
{j++;
g.setColor(Color.RED);
g.fillOval(100,50, 50,50);
g.drawString("红灯亮了"+j+"秒", 100, 120);
}
else
{
g.setColor(Color.BLACK);
g.fillOval(100,50, 50,50);
}

if(yellowStatus==true){
j++;
g.setColor(Color.YELLOW);
g.fillOval(100, 150, 50, 50);
g.drawString("黄灯注意啦"+j+"秒", 100, 220);
}
else
{
g.setColor(Color.BLACK);
g.fillOval(100, 150, 50, 50);

}
if(greenStatus==true){
j++;
g.setColor(Color.GREEN);
g.fillOval(100, 250, 50, 50);
g.drawString("绿灯行"+j+"秒", 100, 320);
}
else
{
g.setColor(Color.BLACK);
g.fillOval(100, 250, 50, 50);
}
g.setColor(c);
}

public void Lauch() {
setTitle("交通灯指示");
setSize(300, 400);
setBackground(Color.BLACK);
addWindowListener(new WindowAdapter() {

public void windowClosing(WindowEvent e) {
System.exit(0);
}

});

setVisible(true);

new Thread(new PaintThread()).start();
}

public static void main(String[] args) {
JiaoTong a=new JiaoTong();
a.Lauch();

}

public class PaintThread implements Runnable
{

public void run() {
for(int i=0;i<80;i++){
switch (i) {
case 0:
j=0;
redStatus=true;
greenStatus=false;
yellowStatus=false;
break;
case 40:
j=0;
redStatus=false;
greenStatus=false;
yellowStatus=true;
break;
case 50:
j=0;
redStatus=false;
greenStatus=true;
yellowStatus=false;
break;
default:
break;
}
repaint();
if(i==79)
i=-1;
try
{
Thread.sleep(1000);

}
catch(InterruptedException e)
{
e.printStackTrace();
}
}

}

}

}

D. java中的线程是个什么具体的内容

这么说吧,电脑系统里有一个任务管理器,任务管理器中有许多进程,一个进程的下面又有很多线程。就是这个意思啊。
例如JAVA的main方法就是一个主线程,程序的执行顺序是自上而下的,如果这个程序没有在这个主线程上创建一个新的线程的话,程序就自上而下的执行,直到程序执行完闭。
如果你在这个主线程上,也就是main方法里创建了一个新的线程,那么这个时候就有两个线程,新的线程开始执行,这个时候主线程并不是停止了,而是一样的继续自上而下的执行,这个时候就有两条线程在执行代码了。
比如有一辆大卡车,遇到到了一个叉路口,这时大卡车就相当于主线程,这个时候只通往一条道路了,如果在叉路口上大卡车里出来了一辆小车,这个时候小车和大卡车分别向两条路上行驶,而并非大卡车会停下来,这个时候的状态就是两个线程在同时运行。
虽说这个比喻不是很好,但很形象!
说白了,我们以前写的那些简单的程序就只有一个线程,就是主线程(main方法),不管有多少判断,循环,它都是自上而下的执行,如果创建了另一个新的线程,这个时候就有两条线同时执行各自的任务了

E. java 中线程是什么东东

线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。由于线程之间的相互制约,致使线程在运行中呈现出间断性。线程也有就绪、阻塞和运行三种基本状态。
线程是程序中一个单一的顺序控制流程.在单个程序中同时运行多个线程完成不同的工作,称为多线程.
线程和进程的区别在于,子进程和父进程有不同的代码和数据空间,而多个线程则共享数据空间,每个线程有自己的执行堆栈和程序计数器为其执行上下文.多线程主要是为了节约CPU时间,发挥利用,根据具体情况而定. 线程的运行中需要使用计算机的内存资源和CPU

F. java 线程实现一个红绿灯问题

关键是启动一个线程控制颜色。代码如下。

import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheledExecutorService;
import java.util.concurrent.TimeUnit;

public class Signal extends Applet {
int width = 200, height = 240;
int w = 50, h = 50;
int x = (width - w) / 2, y1 = (height - h * 3) / 3, y2 = y1 + h, y3 = y2 + h;
Color c = Color.RED;

@Override
public void init() {
ScheledExecutorService exec = Executors.newScheledThreadPool(1);
exec.scheleAtFixedRate(new Runnable() {
@Override
public void run() {
if (c == Color.RED) {
c = Color.YELLOW;
} else if (c == Color.YELLOW) {
c = Color.GREEN;
} else if (c == Color.GREEN) {
c = Color.RED;
}
repaint();
}
}, 5, 5, TimeUnit.SECONDS);
}

@Override
public void paint(Graphics g) {
setBackground(Color.white);

// all gray
g.setColor(Color.LIGHT_GRAY);
g.fillOval(x, y1, w, h);
g.fillOval(x, y2, w, h);
g.fillOval(x, y3, w, h);

if (c == Color.RED) {
g.setColor(Color.RED);
g.fillOval(x, y1, w, h);
} else if (c == Color.YELLOW) {
g.setColor(Color.YELLOW);
g.fillOval(x, y2, w, h);
} else if (c == Color.GREEN) {
g.setColor(Color.GREEN);
g.fillOval(x, y3, w, h);
}
}
}

G. JAVA线程的机制有哪些

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){ }

H. 如何看待Java绿色线程的相关应用效果

Java绿色线程到底是一个怎么回事呢?这些问题需要我们从本质中看问题 。下面我们就来看看Java绿色线程(Green Thread)是一个相对于操作系统线程(Native Thread)的概念 。

操作系统线程(Native Thread)的意思就是,程序里面的线程会真正映射到操作系统的线程,线程的运行和调度都是由操作系统控制的

Java绿色线程(Green Thread)的意思是,程序里面的线程不会真正映射到操作系统的线程,而是由语言运行平台自身来调度 。

当前版本的Python语言的线程就可以映射到操作系统线程 。当前版本的Ruby语言的线程就属于绿色线程,无法映射到操作系统的线程,因此Ruby语言的线程的运行速度比较慢 。

Java线程同步如何才能排除阻塞
Java线程函数关键代码详细讲述
Java线程同步引用基本代码介绍
Java线程控制权源代码的深入探讨
Java线程同步问题在实践中寻找答案

难道说,Java绿色线程要比操作系统线程要慢吗?当然不是这样 。事实上,情况可能正好相反 。Ruby是一个特殊的例子 。线程调度器并不是很成熟 。

目前,线程的流行实现模型就是Java绿色线程 。比如,stackless Python,就引入了更加轻量的绿色线程概念 。在线程并发编程方面,无论是运行速度还是并发负载上,都优于Python 。

另一个更着名的例子就是ErLang(爱立信公司开发的一种开源语言) 。

ErLang的Java绿色线程概念非常彻底 。ErLang的线程不叫Thread,而是叫做Process 。这很容易和进程混淆起来 。这里要注意区分一下 。

ErLang Process之间根本就不需要同步 。因为ErLang语言的所有变量都是final的,不允许变量的值发生任何变化 。因此根本就不需要同步 。

final变量的另一个好处就是,对象之间不可能出现交叉引用,不可能构成一种环状的关联,对象之间的关联都是单向的,树状的 。因此,内存垃圾回收的算法效率也非常高 。这就让ErLang能够达到Soft
Real Time(软实时)的效果 。这对于一门支持内存垃圾回收的语言来说,可不是一件容易的事情 。

I. 简述Java语言中线程的特点。

线程化是允许多个活动共存于一个进程中的工具。大多数现代的操作系统都支持线程,而且线程的概念以各种形式已存在了好多年。Java 是第一个在语言本身中显式地包含线程的主流编程语言,它没有把线程化看作是底层操作系统的工具。
有时候,线程也称作轻量级进程。就象进程一样,线程在程序中是独立的、并发的执行路径,每个线程有它自己的堆栈、自己的程序计数器和自己的局部变量。但是,与分隔的进程相比,进程中的线程之间的隔离程度要小。它们共享内存、文件句柄和其它每个进程应有的状态。
进程可以支持多个线程,它们看似同时执行,但互相之间并不同步。一个进程中的多个线程共享相同的内存地址空间,这就意味着它们可以访问相同的变量和对象,而且它们从同一堆中分配对象。尽管这让线程之间共享信息变得更容易,但您必须小心,确保它们不会妨碍同一进程里的其它线程。
Java 线程工具和 API 看似简单。但是,编写有效使用线程的复杂程序并不十分容易。因为有多个线程共存在相同的内存空间中并共享相同的变量,所以您必须小心,确保您的线程不会互相干扰。
每个 Java 程序都使用线程
每个 Java 程序都至少有一个线程 ― 主线程。当一个 Java 程序启动时,JVM 会创建主线程,并在该线程中调用程序的 main() 方法。
JVM 还创建了其它线程,您通常都看不到它们 ― 例如,与垃圾收集、对象终止和其它 JVM 内务处理任务相关的线程。其它工具也创建线程,如 AWT(抽象窗口工具箱(Abstract Windowing Toolkit))或 Swing UI 工具箱、servlet 容器、应用程序服务器和 RMI(远程方法调用(Remote Method Invocation))。

阅读全文

与java绿色线程相关的资料

热点内容
编译程序输入一个字符串 浏览:402
圆命令画法 浏览:303
如果给电脑e盘文件加密 浏览:801
javaswing项目 浏览:774
androidsdksetup 浏览:1003
pdf怎么设置中文 浏览:126
安卓手机用什么软件看伦敦金 浏览:962
魅族文件夹无名称 浏览:789
苏黎世无人机算法 浏览:872
核桃编程和小码王的融资 浏览:684
微积分教材pdf 浏览:725
写python给微信好友发消息 浏览:336
蚊帐自营米加密 浏览:418
学校推荐核桃编程 浏览:804
湖南农信app怎么导明细 浏览:471
福特abs编程 浏览:508
如何自学安卓手机 浏览:439
以太坊源码共识机制 浏览:910
单片机探测器 浏览:872
demo编程大赛作品怎么运行 浏览:52