多线程的产生来源于实际的需求,多线程可以通过继承Thread类和实现Runnable接口来实现。
Thread:
publicclassshan {
/**
* @param args
*/
publicstaticvoid main(String[] args) {
//TODO Auto-generated method stub
myThread mt=newmyThread();//创建的Thread子类对象mt可代表线程对象
//mt.setDaemon(true);//后台线程随主线程结束而结束
mt.start();
for(int i=0;i<100;i++){
System.out.println(Thread.currentThread().getName()+i);
}
}
}
class myThreadextends Thread{
publicvoid run(){
for(int i=0;i<100;i++){
System.out.println(Thread.currentThread().getName()+i);
}
}
}
Runnable:
public classshan1 {
/**
* @param args
*/
publicstaticvoid main(String[] args) {
//TODO Auto-generated method stub
myThread mt=newmyThread();//创建Runnable接口对象
//mt.setDaemon(true);//后台线程随主线程结束而结束
new Thread(mt,"as").start();//创建的Runnable接口对象只能作为Thread的target
for(int i=0;i<100;i++){
System.out.println(Thread.currentThread().getName()+i);
}
}
}
class myThreadimplements Runnable{
publicvoid run(){
for(int i=0;i<100;i++){
System.out.println(Thread.currentThread().getName()+i);
}
}
}
Java8以后,Runnable接口用@FunctionalInterface修饰(函数是接口),可以通过Lambda表达式创建。
Java5以后,Java提供了Callable接口,它与Runnable接口没有实现关系,所以Callable接口的对象不能作为Thread类的target。
与Runnable接口的run()方法类似,Callable接口也有call()方法作为线程执行体,但call()方法可以有返回值,并且可以声明抛出异常。Future接口代表Callable接口中call()方法的返回值,且为Future接口提供了一个FutureTask实现类。FutureTask类还实现了Runnnable接口,因此可以作为Thread类的target。
Sleep()可以让各个优先级的线程得到执行机会,yield()只能让不低于该优先级的线程得到执行机会。
isAlive()判断线程是否测试线程的状态
join线程
mt.join();//等待mt线程执行完毕才往下执行
有三种重载方式:
Join();//等待被join()的线程执行完毕;
Join(longmillis);//等待被join()的时间最大为millis,若超过,则不再等待;
Join(longmillis,int nanos);//等待被join()的时间最大为millis+nanos
同步代码块:synchronized(obj同步监视器){同步代码块}
同步方法:public synchronized void ….(….){….}
同步方法的同步监视器是this,this代表调用该方法的对象。
当前线程的同步代码块或同步方法执行完毕后,释放同步监视器。
遇到break、return中止代码的执行,释放同步监视器。
遇到未处理的异常,释放同步监视器。
执行了wait()方法,当前线程暂停,释放同步监视器。
调用sleep和yield不会释放同步监视器。
其他线程调用了该线程的suspend将该线程挂起,不会释放同步监视器。
线程通信:通过将与线程相关的变量或者对象传递给别的线程,实现交互。
1. wait(),notify(),nitifyAll()
2. await(),signal(),signalAll()