在Java中创建线程有两种方法:使用Thread类和使用Runnable接口。在使用Runnable接口时需要建立一个Thread实例。因此,无论
是通过Thread类还是Runnable接口建立线程,都必须建立Thread类或它的子类的实例
主线程也有可能在子线程结束之前结束。并且子线程不受影响,不会因为主线程的结束而结束。
在java中,每次程序运行至少启动2个线程。一个是main线程,一个是垃圾收集线程。因为每当使用java命令执行一个类的时候,实
际上都会启动一个JVM,每一个jVM实习在就是在操作系统中启动了一个进程。
main方法其实也是一个线程。在java中所以的线程都是同时启动的,至于什么时候,哪个先执行,完全看谁先得到CPU的资源。
实现Runnable接口比继承Thread类所具有的优势:
如卖票系统,票数count,实现runnable方式启动多个线程,多个线程处理同一个count(一个线程减一后其他线程处理的是减一后
的数据);thread方式启动过个线程,每个线程都有一个count,互不影响(某个线程减一后,其他线程处理的不是该线程减一后的
数据,而是其他线程中自己的数据)
1):适合多个相同的程序代码的线程去处理同一个资源
2):可以避免java中的单继承的限制
3):增加程序的健壮性,代码可以被多个线程共享,代码和数据独立
所谓同步就是在统一时间段中只有有一个线程运行,其他的线程必须等到这个线程结束之后才能继续执行。
采用同步的话,可以使用同步代码块和同步方法两种来完成。
【同步代码块】:
语法格式:
synchronized(同步对象){
//需要同步的代码
}
但是一般都把当前对象this作为同步对象。
【同步方法】
也可以采用同步方法。
语法格式为synchronized 方法返回类型方法名(参数列表){
// 其他代码
}
3、线程合并——join
从上面的方法的列表可以看到,它有3个重载的方法:
void join()
当前线程等该加入该线程后面,等待该线程终止。
void join(long millis)
当前线程等待该线程终止的时间最长为 millis 毫秒。 如果在millis时间内,该线程没有执行完,那么当前线程进入就绪状态,重新等待cpu调度
void join(long millis,int nanos)
等待该线程终止的时间最长为 millis 毫秒 + nanos 纳秒。如果在millis时间内,该线程没有执行完,那么当前线程进入就绪状态,重新等待cpu调度
sleep是静态方法,是谁掉的谁去睡觉,就算是在main线程里调用了线程b的sleep方法,实际上还是main去睡觉,想让线程b去睡觉要在b的代码中掉sleep
- public class Test1 {
- public static void main(String[] args) throws InterruptedException {
- System.out.println(Thread.currentThread().getName());
- MyThread myThread=new MyThread();
- myThread.start();
- myThread.sleep(1000);//这里sleep的就是main线程,而非myThread线程
- Thread.sleep(10);
- for(int i=0;i<100;i++){
- System.out.println("main"+i);
- }
- }
- }