JAVA学习第二十八课(多线程(七))- 停止线程和多线程面试题
2014-10-13 16:28
459 查看
重点掌握
/*
* wait 和 sleep 区别?
* 1.wait可以指定时间也可以不指定
* sleep必须指定时间
* 2.在同步中,对CPU的执行权和锁的处理不同
* wait释放执行权,释放锁 sleep释放执行权,不释放锁
*/
//同步里具备执行资格的线程不止一个,但是能得到锁的只有一个,所以能执行的也只有一个
一、停止线程的方式
不可能让线程一直在运行,所以需要让线程停止
1.定义循环结束标记
一般而言,线程运行代码都是循环的,只要控制了循环就可以结束任务
2.使用interrupt(中断)
结束线程的冻结状态,使线程回到运行状态
PS:stop过时了,不用了
第一种方式:(常用)
class StopThread implements Runnable
{
private boolean flag = true;
public void run()
{
while(flag)
{
System.out.println(Thread.currentThread().getName()+"---");
}
}
public void ChangeFlag()
{
flag = false;
}
}
public class Main
{
public static void main(String[] args)
{
StopThread s = new StopThread();
Thread t1 = new Thread(s);
Thread t2 = new Thread(s);
t1.start(); t2.start();
int i = 0;
while(true)
{
if(++i == 20)//i达到20后结束所有线程
{
s.ChangeFlag();
break;
}
System.out.println("Main.main"+i);
}
System.out.println("Final");
}
}
缺点:
class StopThread implements Runnable
{
private boolean flag = true;
public synchronized void run()
{
while(flag)
{
try {
wait();
} catch (InterruptedException e) {
// TODO: handle exception
System.out.println(Thread.currentThread().getName()+"..."+e);
}
System.out.println(Thread.currentThread().getName()+"-++--");
}
}
public void ChangeFlag()
{
flag = false;
}
}
主线程结束了,t0 t1直接wait()了,如果线程处于了冻结状态,就无法读取标记,所以就引入了第二种结束线程的方式
第二种方式:interrupt
将线程从冻结状态强制恢复到运行状态中,使线程回到具备CPU执行资格的状态,但是会发生中断异常(InterruptException)
class StopThread implements Runnable
{
private boolean flag = true;
public synchronized void run()
{
while(flag)
{
try {
wait();
} catch (InterruptedException e) {
// TODO: handle exception
System.out.println(Thread.currentThread().getName()+"........."+e);
flag = false;//注意处理,不加这个会导致线程继续等待,主线程结束t1 t2未结束
}
System.out.println(Thread.currentThread().getName()+"-++--");
}
}
public void ChangeFlag()
{
flag = false;
}
}
public class Main
{
public static void main(String[] args)
{
StopThread s = new StopThread();
Thread t1 = new Thread(s);
Thread t2 = new Thread(s);
t1.start(); t2.start();
int i = 0;
while(true)
{
if(++i == 20)//i达到20后结束所有线程
{
//s.ChangeFlag();
t1.interrupt();
t2.interrupt();
break;
}
System.out.println("Main.main"+i);
}
System.out.println("Final");
}
}
二、守护线程
setDaemon(boolean)
public class Main
{
public static void main(String[] args)
{
StopThread s = new StopThread();
Thread t1 = new Thread(s);
Thread t2 = new Thread(s);
t1.start();
t2.setDaemon(true);//守护线程,可以理解为后天线程
//后天线程的特点:运行和前台线程一样,和CPU抢夺执行权
// 结束:前台线程必须手动结束,后台线程如果所有的前提线程都结束了,后台线程也跟着结束
t2.start();
int i = 0;
while(true)
{
if(++i == 20)//i达到20后结束所有线程
{
//s.ChangeFlag();
t1.interrupt();
//t2.interrupt();
break;
}
System.out.println("Main.main"+i);
}
System.out.println("Final");
}
}
守护线程简单理解:比如说(英雄联盟)LOL,我方英雄需要守护我方的防御塔,塔没了,守护线程也就没必要存在了
三、线程的其他方法
1.join()
2.setPriority()
class Demo implements Runnable
{
public void run()
{
for(int i = 0;i<20;i++)
System.out.println(Thread.currentThread().getName()+"..."+i);
}
}
public class Main
{
public static void main(String[] args)throws Exception
{
Demo d = new Demo();
Thread t1 = new Thread(d);
Thread t2 = new Thread(d);
t1.start();
t1.join();//t1线程要申请加入进来,运行,也就是t1不完,t2 和 主线程 就不能执行,
//临时假如一个线程,就要用join方法
t2.start();//如果join放在t2.start()后面,那么主线程只等待t1完成后运行,而t1和t2互相争夺执行权
for(int i = 0;i<20;i++)
System.out.println(Thread.currentThread().getName()+".."+i);
}
}
优先级:setPriority
class Demo implements Runnable
{
public void run()
{
for(int i = 0;i<20;i++)
System.out.println(Thread.currentThread().toString()+"..."+i);
}
}
public class Main
{
public static void main(String[] args)throws Exception
{
Demo d = new Demo();
Thread t1 = new Thread(d);
Thread t2 = new Thread(d);
t1.start();
t2.start();
t2.setPriority(Thread.MAX_PRIORITY);
// Thread.MIN_PRIORITY优先级最小1
//Thread.MAX_PRIORITY 有效级最大10
//Thread.NORM_PRIORITY 默认优先级 5
for(int i = 0;i<20;i++)
System.out.println(Thread.currentThread()+".."+i);
}
}
3.线程组
把10个线程放一个组里,如果中断这一组线程,那么这10个线程都中断了
4.yield()暂停当前正在执行的线程,并执行其他线程
class Demo implements Runnable
{
public void run()
{
for(int i = 0;i<20;i++)
{
System.out.println(Thread.currentThread().toString()+"..."+i);
Thread.yield();
}
}
}
多线程面试题:
1.
class Text implements Runnable
{
public void run(Thread t)
{
}
}
//是否编译失败?如果失败错误在哪?
失败,没有实现run方法的覆盖
改法一:
abstract class Text implements Runnable
{
public void run(Thread t)
{
}
}
改法二:重载,进行覆盖
class Text implements Runnable
{
public void run()
{
System.out.println("Text.run()1");
}
public void run(Thread t)
{
System.out.println("Text.run()2");
}
}2.
以子类为主,没有子类以父类为主
/*
* wait 和 sleep 区别?
* 1.wait可以指定时间也可以不指定
* sleep必须指定时间
* 2.在同步中,对CPU的执行权和锁的处理不同
* wait释放执行权,释放锁 sleep释放执行权,不释放锁
*/
//同步里具备执行资格的线程不止一个,但是能得到锁的只有一个,所以能执行的也只有一个
一、停止线程的方式
不可能让线程一直在运行,所以需要让线程停止
1.定义循环结束标记
一般而言,线程运行代码都是循环的,只要控制了循环就可以结束任务
2.使用interrupt(中断)
结束线程的冻结状态,使线程回到运行状态
PS:stop过时了,不用了
第一种方式:(常用)
class StopThread implements Runnable
{
private boolean flag = true;
public void run()
{
while(flag)
{
System.out.println(Thread.currentThread().getName()+"---");
}
}
public void ChangeFlag()
{
flag = false;
}
}
public class Main
{
public static void main(String[] args)
{
StopThread s = new StopThread();
Thread t1 = new Thread(s);
Thread t2 = new Thread(s);
t1.start(); t2.start();
int i = 0;
while(true)
{
if(++i == 20)//i达到20后结束所有线程
{
s.ChangeFlag();
break;
}
System.out.println("Main.main"+i);
}
System.out.println("Final");
}
}
缺点:
class StopThread implements Runnable
{
private boolean flag = true;
public synchronized void run()
{
while(flag)
{
try {
wait();
} catch (InterruptedException e) {
// TODO: handle exception
System.out.println(Thread.currentThread().getName()+"..."+e);
}
System.out.println(Thread.currentThread().getName()+"-++--");
}
}
public void ChangeFlag()
{
flag = false;
}
}
主线程结束了,t0 t1直接wait()了,如果线程处于了冻结状态,就无法读取标记,所以就引入了第二种结束线程的方式
第二种方式:interrupt
将线程从冻结状态强制恢复到运行状态中,使线程回到具备CPU执行资格的状态,但是会发生中断异常(InterruptException)
class StopThread implements Runnable
{
private boolean flag = true;
public synchronized void run()
{
while(flag)
{
try {
wait();
} catch (InterruptedException e) {
// TODO: handle exception
System.out.println(Thread.currentThread().getName()+"........."+e);
flag = false;//注意处理,不加这个会导致线程继续等待,主线程结束t1 t2未结束
}
System.out.println(Thread.currentThread().getName()+"-++--");
}
}
public void ChangeFlag()
{
flag = false;
}
}
public class Main
{
public static void main(String[] args)
{
StopThread s = new StopThread();
Thread t1 = new Thread(s);
Thread t2 = new Thread(s);
t1.start(); t2.start();
int i = 0;
while(true)
{
if(++i == 20)//i达到20后结束所有线程
{
//s.ChangeFlag();
t1.interrupt();
t2.interrupt();
break;
}
System.out.println("Main.main"+i);
}
System.out.println("Final");
}
}
二、守护线程
setDaemon(boolean)
public class Main
{
public static void main(String[] args)
{
StopThread s = new StopThread();
Thread t1 = new Thread(s);
Thread t2 = new Thread(s);
t1.start();
t2.setDaemon(true);//守护线程,可以理解为后天线程
//后天线程的特点:运行和前台线程一样,和CPU抢夺执行权
// 结束:前台线程必须手动结束,后台线程如果所有的前提线程都结束了,后台线程也跟着结束
t2.start();
int i = 0;
while(true)
{
if(++i == 20)//i达到20后结束所有线程
{
//s.ChangeFlag();
t1.interrupt();
//t2.interrupt();
break;
}
System.out.println("Main.main"+i);
}
System.out.println("Final");
}
}
守护线程简单理解:比如说(英雄联盟)LOL,我方英雄需要守护我方的防御塔,塔没了,守护线程也就没必要存在了
三、线程的其他方法
1.join()
2.setPriority()
class Demo implements Runnable
{
public void run()
{
for(int i = 0;i<20;i++)
System.out.println(Thread.currentThread().getName()+"..."+i);
}
}
public class Main
{
public static void main(String[] args)throws Exception
{
Demo d = new Demo();
Thread t1 = new Thread(d);
Thread t2 = new Thread(d);
t1.start();
t1.join();//t1线程要申请加入进来,运行,也就是t1不完,t2 和 主线程 就不能执行,
//临时假如一个线程,就要用join方法
t2.start();//如果join放在t2.start()后面,那么主线程只等待t1完成后运行,而t1和t2互相争夺执行权
for(int i = 0;i<20;i++)
System.out.println(Thread.currentThread().getName()+".."+i);
}
}
优先级:setPriority
class Demo implements Runnable
{
public void run()
{
for(int i = 0;i<20;i++)
System.out.println(Thread.currentThread().toString()+"..."+i);
}
}
public class Main
{
public static void main(String[] args)throws Exception
{
Demo d = new Demo();
Thread t1 = new Thread(d);
Thread t2 = new Thread(d);
t1.start();
t2.start();
t2.setPriority(Thread.MAX_PRIORITY);
// Thread.MIN_PRIORITY优先级最小1
//Thread.MAX_PRIORITY 有效级最大10
//Thread.NORM_PRIORITY 默认优先级 5
for(int i = 0;i<20;i++)
System.out.println(Thread.currentThread()+".."+i);
}
}
3.线程组
把10个线程放一个组里,如果中断这一组线程,那么这10个线程都中断了
4.yield()暂停当前正在执行的线程,并执行其他线程
class Demo implements Runnable
{
public void run()
{
for(int i = 0;i<20;i++)
{
System.out.println(Thread.currentThread().toString()+"..."+i);
Thread.yield();
}
}
}
public class Main { public static void main(String[] args)throws Exception { new Thread()//线程子类 { public void run() { for(int i = 0;i<20;i++) { System.out.println(Thread.currentThread().getName()+"x = "+i); } } }.start(); for(int i = 0;i<20;i++) { System.out.println(Thread.currentThread().getName()+"y = "+i); } Runnable r = new Runnable() { public void run() { for(int i = 0;i<20;i++) { System.out.println(Thread.currentThread().getName()+"z = "+i); } } }; new Thread(r).start(); } }
多线程面试题:
1.
class Text implements Runnable
{
public void run(Thread t)
{
}
}
//是否编译失败?如果失败错误在哪?
失败,没有实现run方法的覆盖
改法一:
abstract class Text implements Runnable
{
public void run(Thread t)
{
}
}
改法二:重载,进行覆盖
class Text implements Runnable
{
public void run()
{
System.out.println("Text.run()1");
}
public void run(Thread t)
{
System.out.println("Text.run()2");
}
}2.
public class Main { public static void main(String[] args)throws Exception { new Thread(new Runnable() { public void run() { // TODO Auto-generated method stub System.out.println("Runnable run"); } }) { public void run() { System.out.println("Thread run"); } }.start();//这段代码编译能通过吗?如果能打印哪一句 } }打印Thread run
以子类为主,没有子类以父类为主
相关文章推荐
- java多线程学习之停止休眠中的线程问题
- Java 多线程 学习笔记 线程的停止
- java基础学习__多线程(停止线程,守护线程,join方法)
- JAVA学习课第二十八届(多线程(七))- 停止-threaded多-threaded面试题
- Java 多线程学习(2)——停止线程
- [置顶] Java 多线程 学习笔记(二)停止线程的几种方法
- Java多线程学习笔记—线程停止
- Java进阶学习2-多线程之停止线程
- java多线程学习总结之四:线程的同步
- Java基础学习5_多线程(线程间通信--等待唤醒机制)
- 学习java多线程的笔记3-使用BlockingQueue阻塞队列来模拟两个线程之间的通信
- Java基础学习__多线程(线程间通信--生产者消费者JDK5.0升级版)
- 学习笔记 java多线程(四)线程间协作
- java多线程学习四:后台线程
- Java基础学习6_多线程(线程间通信--生产者消费者)
- Java多线程学习:线程的生命周期
- java线程学习3——线程的停止
- java多线程学习1-继承Thread类和实现Runnable接口来创建线程
- java多线程学习2-线程栈模型与线程的变量