java-多线程

线程:进程中负责程序执行的单元,一个进程至少有一个线程。

多线程:多个线程同时运行,解决多任务同时进行的需求。如何运行由CPU自己决定,因此多线程的运行有着不确定性。可以合理运用CPU的资源

线程创建方式

一、继承Thread类

public class TestMain {
    public static void main(String[] args) {
        ThreadDemo threadDemo = new ThreadDemo();
        threadDemo.start();
    }
}

ThreadDemo threadDemo = new ThreadDemo();
threadDemo.start();
创建线程:继承Thread类
  • 继承Thread类,覆盖run()方法。

  • 创建线程对象并用start()方法启动线程。

二、实现Runnable接口

package thread.test;

public class RunnableDemo extends  Test implements  Runnable {
    @Override
    public void run() {
        System.out.println("testThread");
    }
}

Thread thread = new Thread(new RunnableDemo());
thread.start();
创建线程:实现Runnable接口
  • 实现Runnable接口,覆盖run()方法。

  • 创建线程对象传入Runnable实例,并用start()方法启动线程

三、Runnable 和 Thread比较

  java中不可多继承,使用Thread会受制于单继承的局限,但接口可以多实现,若要继承于其他类,Runnable更具有优势。

四、实现Callable 接口

package thread.test;

import java.util.concurrent.Callable;

public class CallableDemo implements Callable<String> {

    @Override
    public String call() throws Exception {
        String testThread = "teshThread!";
        return testThread;
    }
}
创建线程:实现Callable接口
package thread.test;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class TestMain {
    public static void main(String[] args) {
        FutureTask<String> futureTask = new FutureTask<String>(new CallableDemo());
        Thread thread = new Thread(futureTask);
        thread.start();
        try {
            String result = futureTask.get();
            System.out.println(result);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}
Callable线程调用:FutureTask
  • 实现Callable接口,覆盖run()方法。

  • 创建Future<V>接口实例,传入Callable接口实例

  • 创建线程对象,传入带Callable的Future实例
  • futureTask.get()获取返回值。

  Future方法解析:

    get() :获取异步执行的结果,如果没有结果可用,此方法会阻塞直到异步计算完成。

    get(Long timeout , TimeUnit unit) :获取异步执行结果,如果没有结果可用,此方法会阻塞,但是会有时间限制,如果阻塞时间超过设定的timeout时间,该方法将抛出异常。

    boolean isDone() :如果任务执行结束,无论是正常结束或是中途取消还是发生异常,都返回true。

    boolean isCanceller() :如果任务完成前被取消,则返回true

    Future是一个接口,无法直接创建,实现类FutureTask:

    

public class FutureTask<V> implements RunnableFuture<V> {}
FutureTask实现RunnableFuture接口
public interface RunnableFuture<V> extends Runnable, Future<V> {
    void run();
}
RunnableFuture实现Runnable和Future接口

五、Callable 和Runnable的区别:

  Callable带有线程结果返回值,Runnable不带返回值

  Callable等价于可以携带结果的 Runnable,并且有三个状态:等待、运行和完成。完成包括所有计算以任意的方式结束,正常结束、取消和异常。

  Callable需要配合FutureTask 使用,FutureTask 可以取消的异步的计算任务(cancale())

六:线程常用方法:

  wait():让线程进入等待状态,直到它被其他线程通过notify()或者notifyAll唤醒,该方法只能在同步方法中调用。

  notify():随机选择一个在该对象上调用wait方法的线程,解除其阻塞状态,该方法只能在同步方法或同步块内部调用。

  notifyAll():解除所有那些在该对象上调用wait方法的线程的阻塞状态,该方法只能在同步方法或同步块内部调用。

  调用这三个方法中任意一个,当前线程必须是锁的持有者,否则会抛出一个 IllegalMonitorStateException 异常。

  sleep():在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)。

  join() :让调用该方法的 Thread 完成 run() 方法里面的东西后,再执行 join() 方法后面的代码

  yield():线程放弃运行,将CPU的控制权让出。使当前线程从执行状态(运行状态)变为可执行态(就绪状态),yield() 方法让出控制权后,还有可能马上被系统的调度机制选中来运行。

七、多线程优点:

优点:

1)适当的提高程序的执行效率(多个线程同时执行)。

2)适当的提高了资源利用率(CPU、内存等)。

缺点:

1)占用一定的内存空间。

2)线程越多CPU的调度开销越大。

3)程序的复杂度会上升。

原文地址:https://www.cnblogs.com/javaLf/p/8594886.html