进程和线程的区别:
1、进程是程序的一次执行过程,是系统运行程序的基本单位。
2、线程是一个比进程更小的执行单位,一个进程可以产生多个线程。
3、每一个进程都有自己专用的内存区域,而进程产生的多个线程则共享这个进程的内存单元。
4、线程执行开销小,但不利于资源的管理和保护;而进程正好相反。
一篇比较形象的解释文章:http://www.ruanyifeng.com/blog/2013/04/processes_and_threads.html
java创建多线程的几种方法:
1、继承Thread类,重写run()方法
public class Test { public static void main(String[] args) { Thread t1 = new Demo1(); t1.start(); Thread t2 = new Demo1(); t2.start(); } } class Demo1 extends Thread { @Override public void run() { System.out.println(Thread.currentThread().getName() + " is running..."); } }
2、实现Runnable接口,重写run()方法
优点:相比于方法1,避免了单继承的局限性
public class Test { public static void main(String[] args) { Thread t1 = new Thread(new Demo2()); t1.start(); Thread t2 = new Thread(new Demo2()); t2.start(); } } class Demo2 implements Runnable { @Override public void run() { System.out.println(Thread.currentThread().getName() + " is running..."); } }
3、使用匿名内部类,跟方法1和方法2没有太大差别,只是使用了匿名内部类简化了写法
public class Test { public static void main(String[] args) { //方式1:继承Thread类 new Thread(){ @Override public void run() { System.out.println(Thread.currentThread().getName() + " is running..."); } }.start(); //方式2:实现Runnable接口 new Thread(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName() + " is running..."); } }).start(); } }
4、上述方法均无法直接获取线程返回值,我们可以使用Callable接口来实现带返回值的线程
Callable接口的泛型即为call()方法的返回值类型
public class Test { public static void main(String[] args) { FutureTask<String> task = new FutureTask<>(new Demo4()); Thread t = new Thread(task); t.start(); System.out.println("task线程开始"); try { System.out.println("task线程执行结果:" + task.get()); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); } System.out.println("main方法结束"); } } class Demo4 implements Callable<String> { @Override public String call() throws Exception { System.out.println(Thread.currentThread().getName() + " is running..."); Thread.sleep(1000); System.out.println(Thread.currentThread().getName() + " is finished..."); return "call result"; } }