为什么java线程不能重复start?Java线程的start方法能调用多次吗
各位老铁们,大家好,今天由我来为大家分享为什么java线程不能重复start,以及Java线程的start方法能调用多次吗的相关问题知识,希望对大家有所帮助。如果可以帮助到大家,还望关注收藏下本站,您的支持是我们最大的动力,谢谢大家了哈,下面我们开始吧!
Java线程的start方法能调用多次吗
一个线程对象只能调用一次start方法.从new到等待运行是单行道,所以如果你对一个已经启动的线程对象再调用一次start方法的话,会产生:IllegalThreadStateException异常.
可以被重复调用的是run()方法。
Thread类中run()和start()方法的区别如下:
run()方法:在本线程内调用该Runnable对象的run()方法,可以重复多次调用;
start()方法:启动一个线程,调用该Runnable对象的run()方法,不能多次启动一个线程;
这个多线程java程序为什么会最开始执行同一个线程两次
Thread t1先执行调用c.manufacture();打印"制造一台电脑" t1等待被t2唤醒wait();
Thread t2执行时调用c.transport();但是没有打印"运走一台电脑"因为"运走一台电脑"没有在c.transport();中wait()前打印,而是在c.transport();调用后打印的,所以这里没有输出.
t2执行唤醒t1 notify();t2等待被t1唤醒wait();注意这时c.transport();并没有执行完,它还在等待被t1唤醒.
Thread t1再执行调用c.manufacture();打印"制造一台电脑"唤醒t2 notify();这时c.transport();执行完了打印"运走一台电脑".然后t1等待被唤醒wait();
Thread t2执行时调用c.transport();但是没有打印"运走一台电脑"唤醒t1 notify();t2 wait();注意这时c.transport();并没有执行完,它还在等待被t1唤醒.
Thread t1执行调用c.manufacture();打印"制造一台电脑"唤醒t2 notify();这时c.transport();执行完了打印"运走一台电脑".然后t1等待被唤醒wait();
上面是造成"制造一台电脑"在开头被打印两次的原因
解决办法就是把打印"运走一台电脑"放到c.transport();函数中wait();语句前,就不会出现打印两次的情况了.
像这样:完整的程序如下:
packageexercise2;
classComputer{
privateintmfg=1;
intstack=0;
publicsynchronizedvoidmanufacture(){
try{
Thread.sleep(50);
}catch(InterruptedExceptione1){
//TODOAuto-generatedcatchblock
e1.printStackTrace();
}
System.out.println("制造一台电脑");
mfg=1;
notify();
if(mfg==1){
try{
wait();
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
}
publicsynchronizedvoidtransport(){
try{
Thread.sleep(50);
}catch(InterruptedExceptione1){
//TODOAuto-generatedcatchblock
e1.printStackTrace();
}
System.out.println("运走一台电脑");//这里加上打印语句
stack+=1;
mfg=0;
notify();
if(mfg==0){
try{
wait();
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
}
}
classproducerimplementsRunnable{
Computerc=null;
publicproducer(Computerc){
this.c=c;
}
@Override
publicvoidrun(){
while(true){
c.manufacture();
}
}
}
classConsumerimplementsRunnable{
Computerc=null;
publicConsumer(Computerc){
this.c=c;
}
@Override
publicvoidrun(){
while(true){
c.transport();
//System.out.println("运走一台电脑");//这里去掉打印语句移动到c.transport();函数中wait语句前
}
}
}
publicclassEx22_2{
publicstaticvoidmain(String[]args){
Computerc=newComputer();
Threadt1=newThread(newproducer(c));
Threadt2=newThread(newConsumer(c));
t1.start();
t2.start();
try{
Thread.sleep(1500);
}catch(InterruptedExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}
t1.stop();
t2.stop();
System.out.println(c.stack);
}
}
运行结果:
制造一台电脑
运走一台电脑
制造一台电脑
运走一台电脑
制造一台电脑
运走一台电脑
制造一台电脑
运走一台电脑
制造一台电脑
运走一台电脑
制造一台电脑
运走一台电脑
制造一台电脑
运走一台电脑
制造一台电脑
运走一台电脑
制造一台电脑
运走一台电脑
制造一台电脑
运走一台电脑
制造一台电脑
运走一台电脑
制造一台电脑
运走一台电脑
制造一台电脑
运走一台电脑
制造一台电脑
运走一台电脑
制造一台电脑
14
Java线程中run和start方法的区别
区别:调用start方法实现多线程,而调用run方法没有实现多线程
Start:
用start方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码。通过调用Thread类的start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到spu时间片,就开始执行run()方法,这里方法run()称为线程体,它包含了要执行的这个线程的内容,Run方法运行结束,此线程随即终止。
Run:
run()方法只是类的一个普通方法而已,如果直接调用Run方法,程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码,这样就没有达到写线程的目的。
总结:调用start方法方可启动线程,而run方法只是thread的一个普通方法调用,还是在主线程里执行。
java thread调用start后,一直没有进入run方法,是什么原因
1.start()方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码:
通过调用Thread类的start()方法来启动一个线程,
这时此线程是处于就绪状态,
并没有运行。
然后通过此Thread类调用方法run()来完成其运行操作的,
这里方法run()称为线程体,
它包含了要执行的这个线程的内容,
Run方法运行结束,
此线程终止,
而CPU再运行其它线程,
2.run()方法当作普通方法的方式调用,程序还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码:
而如果直接用Run方法,
这只是调用一个方法而已,
程序中依然只有主线程--这一个线程,
其程序执行路径还是只有一条,
这样就没有达到写线程的目的。
举例说明一下:
记住:线程就是为了更好地利用CPU,
提高程序运行速率的!
public class TestThread1{
public static void main(String[] args){
Runner1 r=new Runner1();
//r.run();//这是方法调用,而不是开启一个线程
Thread t=new Thread(r);//调用了Thread(Runnable target)方法。且父类对象变量指向子类对象。
t.start();
for(int i=0;i<100;i++){
System.out.println("进入Main Thread运行状态");
System.out.println(i);
}
}
}
class Runner1 implements Runnable{//实现了这个接口,jdk就知道这个类是一个线程
public void run(){
for(int i=0;i<100;i++){
System.out.println("进入Runner1运行状态");
System.out.println(i);
}
}
}
文章到此结束,如果本次分享的为什么java线程不能重复start和Java线程的start方法能调用多次吗的问题解决了您的问题,那么我们由衷的感到高兴!