一、wait 和 sleep 区别?
1,wait可以指定时间也可以不指定。sleep必须指定时间。
2,在同步中时,对cpu的执行权和锁的处理不同。
wait:释放执行权,释放锁。sleep:释放执行权,不释放锁。
二、停止线程方法:
stop方法。(已过时)
run方法结束。
1,怎么控制线程的任务结束呢?
任务中都会有循环结构,只要控制住循环就可以结束任务,控制循环通常就用定义标记来完成,示例:
class StopThread implements Runnable
{
private boolean flag = true;
public synchronized void run()
{
while(flag) //标记
{
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.start();
int num = 1;
for(;;)
{
if(++num==50)
{
st.setFlag(); //将标记置为false
break;
}
System.out.println("main...."+num);
}
System.out.println("over");
}
}
2,但是如果线程处于了冻结状态,无法读取标记。如何结束呢?
可以使用interrupt()方法将线程从冻结状态强制恢复到运行状态中来,让线程具备cpu的执行资格,但是强制动作会发生InterruptedException,记得要处理。示例:
class StopThread implements Runnable
{
private boolean flag = true;
public synchronized void run()
{
while(flag)
{
try
{
wait();
}
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.start();
int num = 1;
for(;;)
{
if(++num==50)
{
t1.interrupt();
t2.interrupt();
break;
}
System.out.println("main...."+num);
}
System.out.println("over");
}
}
三、守护线程(用户线程):setDaemon()
用户线程即后台线程:如果所有前台线程都结束了,后台线程强制结束。
t2.setDaemon(true);//守护线程
四、插入线程
临时加入一个线程运算时可以使用join方法(join方法会执行到该线程结束),例如
class Demo implements Runnable
{
public void run()
{
for(int x=0; x<50; x++)
{
System.out.println(Thread.currentThread().toString()+"....."+x);
Thread.yield();
}
}
}
class JoinDemo
{
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();
t1.join();//t1线程要申请加入进来,运行。临时加入一个线程运算时可以使用join方法。
for(int x=0; x<50; x++)
{
System.out.println(Thread.currentThread()+"....."+x);
}
}
}
五、其他方法
1,优先级(1~10)
MAX_PRIOPITY:使线程具有最高优先级
MIN_PRIOPITY:使线程具有最低优先级
NORM_PRIOPITY:使线程具有默认优先级
2、暂停线程
Thread.yield()
六、面试题
1,如果错误 错误发生在哪一行?
class Test implements Runnable
{
public void run(Thread t)
{}
}
答案:错误在第一行,因为run方法只是Test的特有方法,并未覆写接口中的run方法,所以应该被abstract修饰。
2,下面的代码是否有问题,如果没问题那么输出哪一句?
class ThreadTest
{
public static void main(String[] args)
{
new Thread(new Runnable()
{
public void run()
{
System.out.println("runnable run");
}
})
{
public void run()
{
System.out.println("subThread run");
}
}.start();
}
答案:输出结果为 subThread run ,因为子类覆写了父类的方法,如果没有子类,则以父类的方法为主