Java语言的JVM允许程序运行多个线程,使用java.lang.Thread类代表线程,所有线程对象都必须是Thread类或其他子类的实例
Thread类的特性:
- 每个线程都是通过某个特定的Thread对象的run()方法来完成操作的,因此把run()方法体称为线程执行体
- 通过该Thread对象的start()方法来启动这个线程,而非直接调用run()
- 想要实现多线程,必须在主线程中创建新的线程对象
方式一:使用继承Thread类创建多线程
class Test extends Thread {
//需要重写run方法,且将要执行的操作声明在此方法体中
public void run()
{
//你需要多线程执行的代码
}
}
class Main{
public static void main (String[] args)
{
Test t1 = new Test();
//进行运行,它会调用线程的run方法,注意start一次之后不能再一次start,不然status改变会抛出异常
t1.start();
}
}
方式二:使用Runnable接口创建多线程
class TestRunnable implements Runnable{
public void run(){
//你需要多线程执行的操作
}
}
class Main{
public static void main(String[] args)
{
TestRunnable tr1 = new TestRunnable();
Thread t1 = new Thread(tr1);
t1.start();
}
}
方式三:使用Callable接口创建多线程
与Runnable对比:新增加返回值,更灵活
可以通过throws处理异常
泛型使用也让它更灵活
缺点:如果需要主线程获取分线程的返回值,主线程会处于阻塞状态
class TestCallable implements Callable {
//实现call方法,将此线程需要执行的操作声明在call()中
public Object call() throws Exception
{
//相当于run方法,但有返回类型 也可以通过throws方法抛出异常
}
}
class Main {
public static void main(String[] args)
{
TestCallable tc1 = new TestCallable();
Thread t1 = new Thread(tc1);
t1.start();
//获取返回值
try{
Object ss = t1.get();
}catch(Exception e)
{
e.printStackTrace();
}
}
}
使用线程池创建多线程
提前创建好多个线程,放入线程池中,使用时直接获取,用完则放回池中。避免频繁创建销毁,实现重复利用。
好处:提高程序执行的效率
提高资源的复用率
可以设置相关参数,对线程池的线程使用进行管理
//首先假设我们已经基于Runnable接口的线程方法
public class ThreadPool{
public static void main(String[] args)
{
//1.提供指定线程数量的线程池
ExecutorService service = Executors.newFixedThreadPool(10);
ThreadPoolExecutor service1 = (ThreadPoolExecutor) service;
//2.设置线程池属性
service1.setMaximumPoolSize(50); //设置线程池中线程池的上限
//3.执行指定的线程操作,需要提供实现Runnable接口或Callable接口实现类的对象
service.execute(new RunnableTest());//适合Runnable接口方法
// service.submit(Callable callable); //适合Callable接口方法
//4.关闭线程池
service.shutdown();
}
}