Java如何实现线程的暂停和重新启用?求大神
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java如何实现线程的暂停和重新启用?求大神相关的知识,希望对你有一定的参考价值。
JAVA中线程开始有start方法,暂停用sleep(time)方法,线程停止用stop方法,线程等待wait方法,java 中没有线程重启一说,只能说线程唤醒notifyAll()或是notify方法,前一个notifyAll()方法是唤醒所有的已休眠或是等待状态下的线程。具体的一种参数请参照JDK文档。
Java中的线程的生命周期大体可分为5种状态。如下:
1.新建(NEW):新创建了一个线程对象。
2.可运行(RUNNABLE):线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取cpu 的使用权 。
3.运行(RUNNING):可运行状态(runnable)的线程获得了cpu 时间片(timeslice) ,执行程序代码。
4.阻塞(BLOCKED):阻塞状态是指线程因为某种原因放弃了cpu 使用权,也即让出了cpu timeslice,暂时停止运行。直到线程进入可运行(runnable)状态,才有机会再次获得cpu timeslice 转到运行(running)状态。阻塞的情况分三种:
(一).等待阻塞:运行(running)的线程执行o.wait()方法,JVM会把该线程放入等待队列(waitting queue)中。
(二).同步阻塞:运行(running)的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池(lock pool)中。
(三).其他阻塞:运行(running)的线程执行Thread.sleep(long ms)或t.join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入可运行(runnable)状态。
5.死亡(DEAD):线程run()、main() 方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。死亡的线程不可再次复生。
参考技术A曾经碰到一个问题,线程的暂停与继续,想了想,去使用JDK给我们提供的suspend方法、interrupt方法??suspend()方法让这个线程与主线程都暂停了,谁来唤醒他们??明显这个不好用,要用的话,恐怕得另写唤醒线程了!interrupt方法,这个方法实际上只能中断当前线程!
既然JDK解决不了偶的问题,偶只能自己写了!
这个时候想到了Object的wait()和notifyAll()方法。使用这两个方法让线程暂停,并且还能恢复,我只需要封装一下,就能够变成非常之好用的代码了!如下请看:
新建Thread类继承MyThread只需实现runPersonelLogic()即可跑你自己的逻辑啦!!!
另外调用setSuspend(true)是当前线程暂停/ 等待,调用setSuspend(false)让当前线程恢复/唤醒!自我感觉很好使!
public abstract class MyThread extends Threadprivate boolean suspend = false;
private String control = ""; // 只是需要一个对象而已,这个对象没有实际意义
public void setSuspend(boolean suspend)
if (!suspend)
synchronized (control)
control.notifyAll();
this.suspend = suspend;
public boolean isSuspend()
return this.suspend;
public void run()
while (true)
synchronized (control)
if (suspend)
try
control.wait();
catch (InterruptedException e)
e.printStackTrace();
this.runPersonelLogic();
protected abstract void runPersonelLogic();
public static void main(String[] args) throws Exception
MyThread myThread = new MyThread()
protected void runPersonelLogic()
System.out.println("myThead is running");
;
myThread.start();
Thread.sleep(3000);
myThread.setSuspend(true);
System.out.println("myThread has stopped");
Thread.sleep(3000);
myThread.setSuspend(false);
参考技术B 让线程睡眠,调用线程的sleep(timeout)方法。追问
能给个实例么?
参考技术C JAVA中线程开始有start方法,暂停用sleep(time)方法,线程停止用stop方法,线程等待wait方法,java 中没有线程重启一说,只能说线程唤醒notifyAll()或是notify方法,前一个notifyAll()方法是唤醒所有的已休眠或是等待状态下的线程。具体的一种参数请参照JDK文档。打字不易,望采纳。追问能给个实例么?
追答等等啊,给你找找
追问好的,多谢啦!
追答给我你的邮箱,我发给你
追问发私信吧
追答我这里有视频,全方位的讲解多线程技术,两百多M,邮件比较好。
追问企鹅3086642601
本回答被提问者采纳 参考技术D 那resume呢第一年学java,马上考试了,老师给的重点,求大神指教!!!
第一年学java,马上考试了,老师给的重点,求大神指教!!!
1,java的虚拟机机制
2,java的源程序是如何编译和运行的
3,java常用的基本数据类型
4,J2SE,J2EE,J2ME分别是什么
5,方法的重启,重载
6,什么是多态(方法)
7,this
super 关键词
8,接口
抽象类
9,java中的数组,数组的定义
10,如何比较两个对象是否相等
11,fibonacci数列,编程实现
12,java异常数列处理机制,线程创建和生命周期
有些可能没说清楚,请体谅啊!!!!
2、
Application程序的编写与运行
编写源程序 (例HelloWorld.java)
class HelloWorld
public static void main(String[] args)
System.out.println("Hello World!");
注:保存的时候文件名要和类名一致,包括大小写
编译源程序
首先在附件 –》命令提示符下,进入该文件的根目录(例如)输入“e:”在DOS 下进入E盘
用javac命令编译源文件,如:
javac HelloWorld.java
运行Java程序
p执行java命令就可运行Java程序 ,如:
java HelloWorld
(2)Applet程序的编写与运行
编写源程序 (例MyFirstApplet.java)
import java.applet.*;
import java.awt.*;
public class MyFirstApplet extends Applet
public void paint(Graphics g)
g.drawString("Hello! java world!",2,20);
编译源程序
p 建立MyFirstApplet.html,将MyFirstApplet.class字节码文件放入其中。
<HTML>
<HEAD>
<TITLE> MyFirstApplet program </TITLE>
</HEAD>
<BODY>
<p>
<applet code=MyFirstApplet.class width=300 height=200>
</applet>
</BODY>
</HTML>
浏览MyFirstApplet.html
3、基本类型:
(1)underfined(未定义类型)
(2)null(空类型)
(3)number(数值类型)
(4)string(字符串类型)
(5)boolean(布尔类型)
4、J2SE就是Java2的标准版,主要用于桌面应用软件的编程;
J2ME主要应用于嵌入是系统开发,如手机和PDA的编程;
J2EE是Java2的企业版,主要用于分布式的网络程序的开发,如电子商务网站和ERP系统。
5、在Java 中,同一个类中的2个或2个以上的方法可以有同一个名字,只要它们的参数声明不同即可。在这种情况下,该方法就被称为重载(overloaded ),这个过程称为方法重载(method overloading )。方法重载是Java 实现多态性的一种方式。如果你以前从来没有使用过一种允许方法重载的语言,这个概念最初可能有点奇怪。但是你将看到,方法重载是Java 最激动人心和最有用的特性之一
6、多态通过分离做什么和怎么做,从另一个角度将接口和实现分离开来。多态不但能够改善代码的组织结构和可读性,还能创建可扩展的程序,无论在项目最初还是添加新功能的时候都是可“生长”的程序。简单的来说多态就是将派生类的引用赋给基类,并通过基类的引用调用派生类的方法(前提派生类重写了基类的方法)。多态也称动作绑定,后期绑定或运行时绑定。多态的作用是消除类型之间的耦合关系。
7、this是Javascript语言的一个关键字。
它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用。比如,
function test()
this.x = 1;
随着函数使用场合的不同,this的值会发生变化。但是有一个总的原则,那就是this指的是,调用函数的那个对象。
如果子类中定义的成员变量和父类中成员变量同名时,子类就隐藏了从父类继承的成员变量。当子类中定义了一个方法,并且这个方法的名字、返回类型、参数个数和类型和父类的某个方法完全相同盟时,子类从父类继承的这个方法将被隐藏。如果在子类中想使用被隐藏的成员变量或方法就可以使用关键字。
8、Java中的接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。 接口的两种含义:一,Java接口,语言中存在的结构,有特定的语法和结构;二,一个类所具有的方法的特征集合,是一种逻辑上的抽象。前者叫做“Java接口”,后者叫做“接口”。
抽象类:包含了抽象方法的一个类叫作“抽象类”。如果一个类里包含了一个或多个抽象方法,类就必须指定成 abstract(抽象)。
9、数组:是一组相关变量的集合
数组是一组相关数据的集合,一个数组实际上就是一连串的变量,数组按照使用可以分为一维数组、二维数组、多维数组
数据的有点
不使用数组定义100个整形变量:int i1;int i2;int i3
使用数组定义 int i[100];
数组定义:int i[100];只是一个伪代码,只是表示含义的
10、java里面什么时候可以用==和!=来比较呢?
基本类型数据可以用==和!=来比较,什么是基本类型数据呢?
java里面有规定:boolean char byte short int long float double void都属于基本类型数据,基本类型的数据不需要用new来创建变量,而是创建一个并非是引用的变量,直接存储”值“并置于堆栈中(其它的对象是存储在堆中,堆栈比堆具有更高的存取速度),所以它们可以==和!=来直接比较大小。
如果要比较两个非基本类型的数据是否相等,应该用什么方法呢?
当然是equals()方法,还是上面的例子,如果改为用equals()方法来判断就可以得到想要的结果了
Integer n1 = new Integer(100);
Integer n2 = new Integer(100);
System.out.println(n1.equals(n2));
最终输出的结果是 true 。
虽然结果正如我们所预料的那样,但事情总没那么简单!如果你创建了一个自己的类,例如:
class Value
int i;
然后再来比较这个类的两个对象的值
Value v1 = new Value();
Value v2 = new Value();
v1.i = v2.i = 100;
System.out.println(v1.equals(v2));
最终输出的结果是 false 。
事情再次令人费解了,静下心来好好想想,equals()方法是怎么来的,是时候查查JDK文档了
JAVA中所有的类都继承于object类,而object类中就有equals()方法,但从jdk文档中我们可以知道,这个方法默认比较是对象的引用,而不是对象的内容。而之前Integer类的两个对象之所以能得到正确的结果,是因为Integer 类重写了equals()方法。
一切也就豁然开朗了,如果要比较自己创建的类的两个对象值是否相等就得重写equals()方法了!
11、有界面版:
/*
* Created on 2005-7-22
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/
/**
* @author Administrator
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class FibonacciTest extends JApplet implements ActionListener
JLabel numLabel, resultLabel;
JTextField num, result;
public void init()
Container c = getContentPane();
c.setLayout( new FlowLayout());
numLabel = new JLabel ( " Enter integer and press Enter" );
c.add(numLabel);
num = new JTextField ( 10 );
num.addActionListener( this );
c.add( num );
resultLabel = new JLabel ( "Fibonacci Value is" );
c.add(resultLabel);
result = new JTextField ( 15 );
result.setEditable( false );
c.add ( result );
public void actionPerformed ( ActionEvent e )
long number, fibonacciValue;
number = Long.parseLong(num.getText());
showStatus( "Calculating...");
fibonacciValue = fibonacci( number );
showStatus( "done.");
result.setText( Long.toString(fibonacciValue));
public long fibonacci (long n)
if( n == 0 || n == 1 )
return n;
else
return fibonacci( n - 1 ) + fibonacci( n - 2 );
无界面版:class Fibonacci
public static void main(String[] args)
int i;
int f[]=new int[10];
f[0]=f[1]=1;
for (i=2;i<10 ;i++ )
f[i]=f[i-1]+f[i-2];
for (i=1;i<=10 ;i++ )
System.out.println("F["+i+"]="+f[i-1]);
12、1)异常数列处理机制:程序出现错误后程序如何处理,控制权交给异常处理器。(异常都是在运行中的,不是编译时的) 异常处理流程:遇到错误,方法立即结束,同时抛出一个异常对象。调用该方法的程序停止,并搜索一个可以处理该异常的,并执行其中的代码。 Error及RunTimeException及其子类为未检测异常,及自己会跑出不需要程序员抛出;而其他为已检测异常,需要程序员抛出。
2)线程创建:Java提供了线程类Thread来创建多线程的程序。其实,创建线程与创建普通的类的对象的操作是一样的,而线程就是Thread类或其子类的实例对象。每个Thread对象描述了一个单独的线程。要产生一个线程,有两种方法:
◆需要从Java.lang.Thread类派生一个新的线程类,重载它的run()方法; ◆实现Runnalbe接口,重载Runnalbe接口中的run()方法。
3)生命周期:新建-就绪-(阻塞)-运行--死亡
其中当用new 创建完一个线程对象后,该线程处于新建状态。
当线程对象调用了start()后,该线程处于就绪状态
如果处于就绪状态的线程获得CPU时间片,开始执行run方法的线程执行体,该线程处于运行状态
如果线程调用了sleep()或者调用了一个阻塞式IO方法等,该线程处于阻塞状态
如果线程的run()执行完成或者抛出一个未捕获的异常等原因,该线程处于死亡状态
神啊,累的我写了1个半小时。如果采纳的话,请给分,选为满意答案。 参考技术A 1.JAVA虚拟机的机制
这个问题太大了,以我目前的知识量还不能完全解答,不过你们刚学JAVA不 可 能考这么深拉,下面是我自己的理解,细节上可定没这么准确,但肯定是这么回事就对了。但是想真正了解你就要去看《深入JAVA虚拟机》这书了
要大概理解JAVA虚拟机(JVM)的机制首先你要了解高级语言是怎么一步一步变成机器语言的。首先,以java语言为例子,比如说你在编译器(eclipse或是myeclipse)上编写了一个A.java文件,然后编译器就会把A.java文件编译成A.class文件,然后就进入JAVA虚拟机(JVM)的工作了,JVM里有个类加载器(class loader这个东西很关键)会给A.class文件提供一系列的JAVA API(就是很多class文件,比如说String.class,Object.class等等,但要注意只有A.class文件中用到的类才会被加载,没用到的是不会被加载的),最后就会把这些.class文件交给该JAVA虚拟机的执行引擎(执行引擎具体里面是怎样我也不了解,)把他们解释成你的电脑能直接阅读的10101010的机器语言。
我估计这里如果你的老师再要问的话就是问为什么说JAVA是个跨平台的语言?
首先你要理解什么是跨平台,说白了就是你在windows操作系统下编写的A.java文件放到Linux平台上一样能运行,这样说还不好理解,比如说你在windows操作系统下编写A.java文件中用到了一些windows的方法,然后你要放到Linux上去运行,按道理来说那些windows的方法你在Linux上是找不到的,所以就运行不了的,(注意高潮来了)但是关键点就在这个java api上,java api 写的特别nb,一个平台能运行java语言首先他肯定必须实现java api,所以这个时候java api就会去Linux 去找能运行的方法,然后他就跨平台了。。。。这个是比较细的说法,粗略点来说,就是不同的操作系统对应了不同的Java虚拟机,所以他就跨平台了。。。。
如果你要把java虚拟机的机制说的再说的细点就JVM的类加载器好好说下,这个实在不愿查书了,而且略复杂,详细参考《深入JAVA虚拟机》的第一张,然后你还好奇java虚拟机的运行机制上(其实这才是真正的机制)还是参考《深入JAVA虚拟机》的第5章
2,java的源程序是如何编译和运行的
在上个问题中已经说过了
3,java常用的基本数据类型
基本类型-------整型:1>byte 2>short 3>int 4>long
浮点类型:1>float 2>double
字符类型:char
布尔类型:boolean
特别注意这里没有string ,字符串string 是引用类型不是基本类型
4,J2SE,J2EE,J2ME分别是什么
简单说就是一大堆接口,他们的区分呢就是应用范围上的划分(感觉百度百科上说的比较准确就抄过来了)
J2SE: java 2 Standard edition 简称java2标准版 他包含那些构成Java语言核心的类比 如:数据库连接、接口定义、输入/输出、网络编程。主要用来开发桌面应用系统
J2EE:java 2 Enterprise Edition(企业版) J2EE 包含J2SE 中的类,并且还包含用于开发企业级应用的类。比如:EJB、servlet、JSP、XML、事务控制 。主要用来开发企业级的应用
J2ME:Micro Edition(微缩版) J2ME 包含J2SE中一部分类,用于消费类电子产品的软件开发。比如:呼机、智能卡、手机、PDA、机顶盒 。主要用来开发适用于小型设备和智能卡的应用
5,方法的重启,重载
一楼说的不错,不过没有方法的重启这种说法,硬要说的话只能理解成重新运行了
6,什么是多态(方法)
多态就是多种形态。你就这么理解同一件事情不同人去作表现的形态是不一样的。比如说一句话,你可以把它写出来,也可以唱出来,还可以说出来。
方法的多态的表现形式就是方法的重载喽
7,this
super 关键词
看到一楼的解释才发现原来他是粘贴的。。。
this是指当前的对象,简单来说的他出现是为了省代码用的,你可以用this.XXX的方式调用当前类的函数或是变量,用的时候就是在写内部类的时候小心点。
super是指父类对象,比如说B继承了A,你在B中想调用A里的东西,可以super.XXX的方式调用,特别注意如果在B中写构造函数时还想要加一句super();有没有参数要看A的构造函数时怎么写的。
8,接口 抽象类
接口和抽象类,简单来说接口里不能有实现,而抽象类中可以有。具体的可以看你的课本
9,java中的数组,数组的定义
这个自己看书吧,太罗嗦了
10,如何比较两个对象是否相等
这个1楼说的不错
11,fibonacci数列,编程实现
一楼正解
12,java异常数列处理机制,线程创建和生命周期
一楼正解
希望我说的能对你有帮助^@^ 参考技术B 楼上够详细了。
以上是关于Java如何实现线程的暂停和重新启用?求大神的主要内容,如果未能解决你的问题,请参考以下文章