Java多线程——实现
“java多线程的实现——几乎都要和java.lang.Thread打交道”
方式一:继承于Thread类
1、创建一个继承于Thread类的子类
2、重写Thread类的run()
3、创建Thread类的子类对象
4、通过此对象调用start():1启动当前线程 2调用当前线程的run()
class MyThread extends Thread{ //继承Thread类
//重写run方法
@Override
public void run() {
for(int i=0;i<100;i++)
{
if(i%2==0)
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
public class ThreadTest {
public static void main(String[] args) {
//方式一
MyThread t1=new MyThread();
t1.start(); //start():1启动一个线程 2执行run()
for(int i=0;i<100;i++) //主线程
if(i%2==1)
System.out.println(Thread.currentThread().getName()+":"+i);
// //方式二
// MyRunnable r1=new MyRunnable();
// new Thread(r1).start();
}
}
ps:
如果main中直接调用t1.run,并不会有新线程,仍然是main的原线程调用了run方法而已
如果线程已经start,不能再进行start(可从代码中发现会报异常)
Thread类中的常用方法
- 构造器可以设置线程名
- start():启动当前线程;调用当前线程的run()
- run(): 线程所做的事务,实现多线程通常重写此方法
- Thread.currentThread():静态方法,返回执行当前代码的线程对象
- setName():设置线程名
- getName():返回线程名
- yield():释放当前执行线程对cpu的执行权(但下次cpu调度仍然可能是ta)
- join():在线程a中调用线程b的join(),此时a进入阻塞直到b执行完后才唤醒a
- Thread.sleep(m):当前执行进程进入睡眠m毫秒
(当前线程进入阻塞态并释放cpu,但不会释放锁,所以一段时间内会无任何线程运行。睡眠结束后被阻塞的进程进入就绪状态——也就是仍然要与其他线程抢夺cpu) - isLive():判断线程是否仍然存活
Thread类中的优先级
- MAX_PRIORITY:10
MIN_PRIORITY:1
NORM_PRIORITY:5 -->默认优先级 - 如何获取和设置当前线程的优先级:
getPriority():获取线程的优先级
setPriority():设置线程的优先级
-PS:高优先级的线程只是更大概率抢占低优先级线程的cpu执行权,不一定百分百。
方式二:创捷一个实现Runnable接口的类并创建其对象
该对象传入Thread的构造器当中
这里可以理解成实现一个Runnable事务类,并创建事务对象传入不同线程对象(同一事务不同线程)
1、创建一个实现了Runnable接口的类
2、实现类去实现Runnable中的抽象方法:run()
3、创建实现类的对象
4、将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象
5、通过Thread类的对象调用start()
MyRunnable r1=new MyRunnable();
new Thread(r1).start();
案例实现:创建三个窗口卖票,总票数为100张
- 使用Thread方式(需要在MyThread类中设置静态变量来表示票数)
- 实现Runnable接口的实现类(只有一个实现类的对象,在对象中设置表示票数的变量即可)
开发中更适合用实现接口(第二种方式),没有单继承局限性同时也更适合共享数据的情况
传统多线程实现方式为两种,但最新jdk支持另外两种方式
守护线程和用户线程