黑马程序员_日记19_Java多线程(九)
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了黑马程序员_日记19_Java多线程(九),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含5558字,纯文字阅读大概需要8分钟。
内容图文
——- android培训、java培训、期待与您交流! ———-
1 停止线程
原理:让run方法结束。而run方法中通常定义循环结构,所以就是控制住循环结构就可以了。
stop方法已经过时了。
如何控制循环结构??
1 定义结束标记
2 当线程处于了冻结状态,没有执行标记,程序一样无法结束。
这时可以循环,正常退出冻结状态,或者强制结束冻结状态。
强制结束冻结状态:interrupt();目的是线程强制从冻结状态恢复到运行状态。
但是会发生InterruptedException异常。
//1 定义结束标记结束线程
class
StopThread
implements
Runnable
{
boolean flag = true;//定义标记控制循环结构//覆盖run方法publicvoid run()
{
while(flag)
{
System.out.println(Thread.currentThread().getName()+"...run");//打印调用run方法的线程名
}
}
//改变标记publicvoid changeFlag()
{
flag = false;
}
}
classStopThreadDemo
{publicstaticvoid main(String[] args)
{
StopThread st = new StopThread();//建立实现了Runnable接口的类的对象
Thread t1 = new Thread(st);//建立线程1
Thread t2 = new Thread(st);//建立线程2
t1.start();//启动线程1,调用run方法
t2.start();//启动线程2,调用run方法//定义一个循环,等线程1和线程2运行一会儿之后,主线程再把标记flag改为falseint num = 0;
while(true)
{
if(num++ == 50)
{
st.changeFlag();//改变run方法中while循环的标记break;//改变标记后,立刻结束主线程的while循环
}
System.out.println(Thread.currentThread().getName()+"......run"+num);//展示主线程执行的结果
}
System.out.println("over");//表示主线程执行完毕
}
}
部分运行结果:
Thread-0…run
Thread-0…run
Thread-1…run
Thread-0…run
main……run50
Thread-0…run
Thread-1…run
over
从控制台中,可以看到,当主线程运行while循环50次后,
就从while循环中跳出来,并执行结束了。
而且线程1和线程也结束了。
下面看一下当线程处于冻结状态时候如何结束线程
class
StopThread
implements
Runnable
{
boolean flag = true;//定义标记控制循环结构//覆盖run方法,注意只有在同步中才可以使用waitpublic synchronized void run()
{
while(flag)
{
try
{
wait();
}
catch (InterruptedException e)
{
System.out.println(Thread.currentThread().getName()+"...异常");
flag = false;//中断线程的冻结状态后,立即改变标记,结束循环,结束run,结束线程
}
System.out.println(Thread.currentThread().getName()+"...run");//打印调用run方法的线程名
}
}
}
classStopThreadDemo
{publicstaticvoid main(String[] args)
{
StopThread st = new StopThread();//建立实现了Runnable接口的类的对象
Thread t1 = new Thread(st);//建立线程1
Thread t2 = new Thread(st);//建立线程2
t1.start();//启动线程1,调用run方法
t2.start();//启动线程2,调用run方法//定义一个循环,等线程1和线程2运行一会儿之后,主线程再把标记flag改为falseint num = 0;
while(true)
{
if(num++ == 50)
{
t1.interrupt();//强制清楚线程1的冻结状态
t2.interrupt();//强制清楚线程1的冻结状态break;//改变标记后,立刻结束主线程的while循环
}
System.out.println(Thread.currentThread().getName()+"......run"+num);//展示主线程执行的结果
}
System.out.println("over");//表示主线程执行完毕
}
}
在把run方法改为下面这样的时候
public synchronized voidrun()
{
while(flag)
{
try
{
this.wait();
}
catch (InterruptedException e)
{
}
System.out.println(Thread.currentThread().getName()+"...run");//打印调用run方法的线程名
}
}
运行结果显示:
线程1和线程2一调用run方法就陷入冻结状态。
而且,直到主线程结束,它们也没有结束。
对此,我们利用interrupt方法来强制中断线程的冻结状态。
总结:
特殊情况:
当线程处于了冻结状态。
就不会读取到标记。那么线程就不会结束。
当没有指定的方式让冻结的线程恢复到运行状态是,这时需要对冻结进行清除。
强制让线程恢复到运行状态中来。这样就可以操作标记让线程结束。
Thread类提供该方法 interrupt();
2 线程中一些常见的方法
2.1 守护线程
setDaemon(boolean)
:将线程标记为后台线程,后台线程和前台线程一样,开启,一样抢执行权运行,
只有在结束时,有区别,当前台线程都运行结束后,后台线程会自动结束。
把前面结束线程的例子改动一下。
class
StopThread
implements
Runnable
{
boolean flag = true;//定义标记控制循环结构//覆盖run方法,publicvoid run()
{
while(flag)
System.out.println(Thread.currentThread().getName()+"...run");//打印调用run方法的线程名
}
}
classStopThreadDemo
{publicstaticvoid main(String[] args)
{
StopThread st = new StopThread();//建立实现了Runnable接口的类的对象
Thread t1 = new Thread(st);//建立线程1
Thread t2 = new Thread(st);//建立线程2
t1.setDaemon(true);//标记线程1为后台线程
t2.setDaemon(true);//标记线程2为后台线程
t1.start();//启动线程1,调用run方法
t2.start();//启动线程2,调用run方法//定义一个循环,等线程1和线程2运行一会儿之后,主线程再把标记flag改为falseint num = 0;
while(true)
{
if(num++ == 50)
{
break;//改变标记后,立刻结束主线程的while循环
}
System.out.println(Thread.currentThread().getName()+"......run"+num);//展示主线程执行的结果
}
System.out.println("over");//表示主线程执行完毕
}
}
运行结果
Thread-0…run
Thread-1…run
main……run50
Thread-1…run
Thread-0…run
Thread-1…run
over
Thread-1…run
结果显示:当主线程结束之后,线程1和线程2立刻结束了
2.2 join方法
join方法:抢夺CPU执行权,直到该线程执行结束,才放弃CPU执行权。
例如,当主线程碰到t1.join()时,主线程就挂起,让出CPU给线程t1,
当线程t1结束后,主线程才重新启动。
示例如下。
class
Join
implements
Runnable
{
public
void run()
{
for(int i =0;i < 50; i++)
{
System.out.println(Thread.currentThread().toString()+"is running..."+i);
Thread.yield();
}
}
}
classJoinDemo
{publicstaticvoid main(String[] args)throws InterruptedException
{
Join j =new Join();
Thread t1 = new Thread(j);
Thread t2 = new Thread(j);
//t1.setPriority(Thread.MIN_PRIORITY);
t1.start();
//t1.setPriority(Thread.MAX_PRIORITY);//t1.join();//线程t1调用Join方法,观察main打印结果
t2.start();
/*
for(int i = 0;i < 60; i++)
System.out.println(Thread.currentThread().getName()+"is running............"+i);*/
System.out.println("over");
}
}
运行结果显示,当线程t1运行完毕之后,才开始执行t2和主线程。
小结:
join():什么意思?等待该线程结束。当A线程执行到了B的.join方法时,A就会处于冻结状态。
A什么时候运行呢?当B运行结束后,A就会具备运行资格,继续运行。加入线程,可以完成对某个线程的临时加入执行。
2.3 yield方法
yield:临时暂停,可以让线程是释放执行权。
在run方法里面添加Thread.yield();
结果为:
Thread[Thread-0,5,main]is running…0
Thread[Thread-1,5,main]is running…1
Thread[Thread-0,5,main]is running…1
Thread[Thread-0,5,main]is running…2
Thread[Thread-0,5,main]is running…3
Thread[Thread-1,5,main]is running…2
Thread[Thread-0,5,main]is running…4
Thread[Thread-1,5,main]is running…3
Thread[Thread-0,5,main]is running…5
Thread[Thread-1,5,main]is running…4
Thread[Thread-0,5,main]is running…6
Thread[Thread-1,5,main]is running…5
两线程在交替执行。
yield()达到了平均分配CPU的效果
3 线程组和优先级
线程组:谁开启就属于谁。样例如下:
Thread[Thread-0,10,main]is running…49
Thread[Thread-1,5,main]is running…49
默认优先级为5,只有1,5,10最明显
public
static
final
int MIN_PRIORITY = 1;
publicstaticfinalint MAX_PRIORITY = 10;
publicstaticfinalint NORM_PRIORITY = 1;
4 wait和sleep的区别
wait和sleep的区别:
wait:释放cpu执行权,释放同步中锁。
sleep:释放cpu执行权,不释放同步中锁。
原文:http://blog.csdn.net/itheima_1llt/article/details/44814711
内容总结
以上是互联网集市为您收集整理的黑马程序员_日记19_Java多线程(九)全部内容,希望文章能够帮你解决黑马程序员_日记19_Java多线程(九)所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。