请说一下 wait 和 sleep 区别?
1,wait可以指定时间也可以不指定。
sleep必须指定时间。
2,在同步中时,对cpu的执行权和锁的处理不同。
( 执行权必须释放,不然电脑就废了!!!!)
wait:释放执行权,释放锁。
sleep:释放执行权,不释放锁。
class Demo
{
void show()
{
synchronized(this)//
{
wait();//t0 t1 t2 都会在这 wait挂着---当 notifyAll 后 t0 t1 t2 都活了,
//具备CPU执行资格 但是此时 t0 t1 t2 还没有持有锁, 没有执行权, t4 退出释放锁
//假设此时 t0 获得锁,t0 执行 ,此时t1 t2 是没办法执行的,除非 t0 结束释放锁。(分析)
}
}
void method()
{
synchronized(this)//t4
{
//wait();
notifyAll();
}//t4
}
}
class
{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}
interrupt 使用
/*
停止线程:
1,stop方法。已经过时 不安全
2,run方法结束。
怎么控制线程的任务结束呢?
任务中都会有循环结构,只要控制住循环就可以结束任务。
控制循环通常就用定义标志位来完成。
但是如果线程处于了冻结状态,无法读取标记。如何结束呢?
用notify ? notify 需要同一个锁 不可取。
[可以使用interrupt()方法将线程从冻结状态wait()强制恢复到运行状态中来,让线程具备cpu的执行资格]。
当时强制动作会发生了InterruptedException,记得要处理
*/
class StopThread implements Runnable
{
private boolean flag = true;
public synchronized void run()//同步
{
while(flag)
{
try
{
wait();//t0 t1一进来就在 wait 等待 此时set flag 也无效
// 需要 interrupt() 抛出异常。
}
catch (InterruptedException e)
{
System.out.println(Thread.currentThread().getName()+"....."+e);
flag = false;
}
System.out.println(Thread.currentThread().getName()+"......++++");
}
}
public void setFlag()//设置标志位让线程退出
{
flag = false;
}
}
class StopThreadDemo
{
public static void main(String[] args)
{
StopThread st = new StopThread();
Thread t1 = new Thread(st);
Thread t2 = new Thread(st);
t1.start();
t2.setDaemon(true);
t2.start();
int num = 1;
for(;;)
{
if(++num==50)
{
// st.setFlag();
t1.interrupt();
// t2.interrupt();
break;// break 退出 只是主线程退出 子线程 还在运行 所以电泳 st.setFlag();
}
System.out.println("main...."+num);
}
System.out.println("over");
}
}
守护进程 (后台线程)
前台线程退出后台线程也会跟着退出不管这个线程是不是被冻结了。
package thread;
class DaemonTest implements Runnable{
@Override
public void run() {
System.out.println(" setDaemon");
try{
this.wait();//冻结
}catch ( InterruptedException e){
e.printStackTrace();
}
}
}
public class DaemonDemo {
public static void main(String[] args) {
DaemonTest daemonTest =new DaemonTest();
Thread thread =new Thread(daemonTest);
//启动之前调用setDaemon --后台线程
thread.setDaemon(true);
thread.start();
System.out.println("main over");
}
}
class DaemonTest implements Runnable{
Object obj=new Object();
@Override
public void run() {
synchronized (obj){
while (true){
System.out.println(" setDaemon");
try{
// this.wait();//冻结
obj.wait();
}catch ( InterruptedException e){
e.printStackTrace();
}
}
}
}
}
public class DaemonDemo {
public static void main(String[] args) {
DaemonTest daemonTest =new DaemonTest();
Thread thread =new Thread(daemonTest);
//启动之前调用setDaemon --后台线程
thread.setDaemon(true);
thread.start();
System.out.println("main over");
}
}
Join 方法用法
例如在 main 函数一个线程t1 调用这个方法 ,那么 main 函数会释放CPU执行权 被冻结,等待这个t1 线程执行结束后再获得执行资格。
Demo:
package thread;
import java.awt.image.ImagingOpException;
class Join implements Runnable {
@Override
public void run() {
for(int i=0;i<10;i++){
System.out.println("等待 Join 执行完"+i);
}
System.out.println("Join 插入执行完成");
}
}
public class JoinDemo {
public static void main(String[] args) {
Join join =new Join();
Thread thread =new Thread(join);
thread.start();
try{
thread.join();
}catch (InterruptedException e){
System.out.println(" intrrupt");
}
System.out.println("main over");
}
}
执行结果:等待 Join 执行完0
等待 Join 执行完1
等待 Join 执行完2
等待 Join 执行完3
等待 Join 执行完4
等待 Join 执行完5
等待 Join 执行完6
等待 Join 执行完7
等待 Join 执行完8
等待 Join 执行完9
Join 插入执行完成
main over
如果有:
t1.start();
t2.start();
t1.join();
那么这时main 是等待 t1 线程结束。
优先级:
1--5--10
优先级代表获取CPU 执行权的几率。(级别 1-10)
toString 方法
面试题1 :
class Test implements Runnable{
public void run(Thread t){}
}//如果错误错误发生在哪一行?
答案:错误在第一行,Test 不是抽象类,并且未覆盖 Runnable 中的抽象方法。应该被 abstract 修饰。
面试题2 :
package thread;
public class ThreadTest {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(" runnable run ");
}
}) {
public void run()
{
System.out.println(" sub run ");
}
}.start();
}
}
输出结果:sub run 以子类为主
如果 没有 { public void run() { System.out.println(" sub run "); } 则输出 runnable run 以任务为主