线程:进程中负责程序执行的单元,一个进程至少有一个线程。
多线程:多个线程同时运行,解决多任务同时进行的需求。如何运行由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类,覆盖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接口,覆盖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; } }

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接口,覆盖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)程序的复杂度会上升。