创建一个线程:
一般而言需要创建一个线程时,需要使用一个子类继承Thread类,并且重写里面的run()方法,在run()里可以写入需要执行的操作功能,当需要创建线程时,可以new出子类的对象,然后使用子类对象调用start()方法,注意:不能直接调用run()方法,否则只是简单的方法调用,而不是线程调用。start()方法中自带对run()方法的调用,线程通过子类对象.start()开始。
创建多个线程:
只需要new多个对象调用start()方法即可。
创建多个不同功能对象:
此时需要多个不同子类继承Thread类,并且重写run()方法,加入不同需求功能。
public class ThreadTest {
public static void main(String[] args) {
myThread my1 = new myThread();
my1.start(); //创建第一线程
myThread my2 = new myThread();
my2.start(); //创建和my1相同功能的线程
myThread1 my3 = new myThread1(); //myThread1为另外重写run()方法的子类
my3.start(); //创建和my1不同相同功能的线程
for (int i = 0; i < 100; i++) {
if (i % 2 == 0){
System.out.println(i+"***************");
}
}
}
}
class myThread extends Thread{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
if (i % 2 == 0){
System.out.println(Thread.currentThread().getName()+ ":" + i); //通过此方法可以查看不同线程名
}
}
}
}
class myThread1 extends Thread{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
if (i % 3 == 0){
System.out.println(Thread.currentThread().getName()+ ":" + i); //通过此方法可以查看不同线程名
}
}
}
}
因为一个线程的创建只要继承重写一次,所以可以考虑用匿名类创建线程:
//通过匿名类开启线程
new Thread(){
@Override
public void run() {
for (int i = 0; i < 100; i++) {
if (i % 2 == 0){
System.out.println(Thread.currentThread().getName()+ ":" + i); //通过此方法可以查看不同线程名
}
}
}
}.start();
关于yield()方法:
指的是释放当前cpu的执行权,一个限权一开始抢到cpu的执行权,一直优先执行,导致另一个限权一直未被执行,此时加上此方法,则两个限权可以重新争取此执行权,注意的是,原来的限权还是有可能继续抢到cpu的执行权。通俗来讲就是,甲乙两个人赛跑,一开始是同一起点,他们相互竞争赛跑,有时候甲跑在前,有时候乙跑在前,若甲发力,一直把乙抛在身后,此时说甲一直抢到优势。裁判黑心了,说你们停下,现在你们两个别跑了,继续从同一个地方出发赛跑,此时甲乙两方重新赛跑抢得优势,两个人都有可能抢得优势。
关于join()方法:
指的是线程在达到某个条件后,暂停该线程执行,加入另一个线程的执行权,直到另一个线程执行完了,原来的线程才会接着执行(原来线程进入阻塞状态)。通俗就是一群普通群众在排队买票,但是得到消息,有一个排的士兵需要优先买票,所以此时群众暂停买票,等候士兵买票完成后,群众即可继续买票
关于sleep()方法:
指的是使线程“睡眠”一定时长再执行,例如上面子类myThread的输出偶数,在run()方法中加入sleep(1000);指的是休眠1秒后继续执行。注意此处会抛出一个异常,但是不能使用throws抛出,因为myThread类的父类Thread中没有使用throws抛出,所以子类也不能用throws,只能使用try...catch。
关于isAlive()方法:
判断线程是否还存活,需要子类对象调用该方法,其返回值为boolean类型。