进程和线程的区别:
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";
}
}