线程和进程区别
- 每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销。
- 线程可以看成时轻量级的进程,同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换的开销小。
- 多进程: 在操作系统中能同时运行多个任务(程序)
- 多线程: 在同一应用程序中有多个顺序流同时执行
线程的创建和启动
可以有两种方式创建新的线程。
第一种 定义线程类实现Runnable接口
public class TestRunnable { public static void main(String[] args) { Runner1 r = new Runner1(); r.run(); Thread t = new Thread(r); t.start(); for (int i=0; i<10; i++) { System.out.println("Main Thread:---" + i); } } } class Runner1 implements Runnable { public void run() { for (int i=0; i<10; i++) { System.out.println("Runner:-------" + i); } } }
输出结果:
Compiling TestRunnable.java....... -----------OUTPUT----------- Runner:-------0 Runner:-------1 Runner:-------2 Runner:-------3 Runner:-------4 Runner:-------5 Runner:-------6 Runner:-------7 Runner:-------8 Runner:-------9 Main Thread:---0 Main Thread:---1 Main Thread:---2 Main Thread:---3 Main Thread:---4 Runner:-------0 Main Thread:---5 Runner:-------1 Main Thread:---6 Runner:-------2 Main Thread:---7 Runner:-------3 Main Thread:---8 Runner:-------4 Main Thread:---9 Runner:-------5 Runner:-------6 Runner:-------7 Runner:-------8 Runner:-------9
第二种 可以定义一个Thread的子类并重写其run方法如:
public class TestThread { public static void main(String[] args) { Thread t = new Runner2(); t.start(); for (int i=0; i<10; i++) { System.out.println("Mainthread:" + i); } } } class Runner2 extends Thread { public void run() { System.out.println(Thread.currentThread().isAlive()); for (int i=0; i<10; i++) { System.out.println("Subthread:" + i); } } }
输出结果:
Compiling TestThread.java....... -----------OUTPUT----------- Mainthread:0 true Mainthread:1 Subthread:0 Mainthread:2 Subthread:1 Mainthread:3 Subthread:2 Mainthread:4 Subthread:3 Mainthread:5 Subthread:4 Mainthread:6 Subthread:5 Mainthread:7 Subthread:6 Mainthread:8 Subthread:7 Mainthread:9 Subthread:8 Subthread:9
线程状态转换
线程控制基本方法
sleep/join/yield 方法
join()
public class TestJoin { public static void main(String[] args) { MyThread1 t1 = new MyThread1(" leaf"); t1.start(); try { t1.join(); } catch (InterruptedException e) {} for (int i=0; i<=10; i++) { System.out.println("i am main thread"); } } } class MyThread1 extends Thread { MyThread1(String s) { super(s); } public void run() { for (int i=0; i<=10; i++) { System.out.println("i am" + getName()); try { sleep(1000); } catch (InterruptedException e) { return; } } } }
输出结果:
Compiling TestJoin.java....... -----------OUTPUT----------- i am leaf i am leaf i am leaf i am leaf i am leaf i am leaf i am leaf i am leaf i am leaf i am leaf i am leaf i am main thread i am main thread i am main thread i am main thread i am main thread i am main thread i am main thread i am main thread i am main thread i am main thread i am main thread
yield()
public class TestYield { public static void main(String[] args) { MyThread3 t1 = new MyThread3("t1"); MyThread3 t2 = new MyThread3("t2"); t1.start(); t2.start(); } } class MyThread3 extends Thread { MyThread3(String s) { super(s); } public void run() { for (int i = 1; i <= 10; i++) { System.out.println(getName() + ": " + i); if (i % 10 == 0) { yield(); } } } }
输出结果:
Compiling TestYield.java....... -----------OUTPUT----------- t2: 1 t1: 1 t2: 2 t1: 2 t2: 3 t1: 3 t2: 4 t1: 4 t2: 5 t1: 5 t2: 6 t1: 6 t2: 7 t1: 7 t2: 8 t1: 8 t2: 9 t1: 9 t2: 10 t1: 10
线程的优先级别
public class TestPriority { public static void main(String[] args) { Thread t1 = new Thread(new T1()); Thread t2 = new Thread(new T2()); t1.setPriority(Thread.NORM_PRIORITY + 3); t1.start(); t2.start(); } } class T1 implements Runnable { public void run() { for(int i=0; i<100; i++) { System.out.println("T1: " + i); } } } class T2 implements Runnable { public void run() { for(int i=0; i<100; i++) { System.out.println("------T2: " + i); } } }
输出结果:
Compiling TestPriority.java....... -----------OUTPUT----------- T1: 0 ------T2: 0 T1: 1 ------T2: 1 T1: 2 ------T2: 2 T1: 3 ------T2: 3 T1: 4 ------T2: 4 ------T2: 5 ------T2: 6 ------T2: 7 T1: 5 T1: 6 T1: 7 T1: 8 T1: 9 ------T2: 8 T1: 10 ------T2: 9 T1: 11 ------T2: 10 T1: 12 ------T2: 11 T1: 13 ------T2: 12 T1: 14 ------T2: 13 T1: 15 ------T2: 14 T1: 16 ------T2: 15 T1: 17 ------T2: 16 T1: 18 ------T2: 17 T1: 19 ------T2: 18 T1: 20 ------T2: 19 T1: 21 ------T2: 20 T1: 22 ------T2: 21 T1: 23 ------T2: 22 T1: 24 ------T2: 23 T1: 25 ------T2: 24 T1: 26 ------T2: 25 T1: 27 ------T2: 26 T1: 28 ------T2: 27 T1: 29 ------T2: 28 T1: 30 ------T2: 29 T1: 31 ------T2: 30 T1: 32 ------T2: 31 T1: 33 ------T2: 32 T1: 34 ------T2: 33 T1: 35 ------T2: 34 T1: 36 ------T2: 35 ------T2: 36 T1: 37 ------T2: 37 T1: 38 ------T2: 38 T1: 39 ------T2: 39 T1: 40 ------T2: 40 T1: 41 ------T2: 41 T1: 42 ------T2: 42 T1: 43 ------T2: 43 T1: 44 ------T2: 44 T1: 45 ------T2: 45 T1: 46 ------T2: 46 T1: 47 ------T2: 47 T1: 48 ------T2: 48 T1: 49 ------T2: 49 T1: 50 ------T2: 50 T1: 51 ------T2: 51 T1: 52 ------T2: 52 T1: 53 ------T2: 53 T1: 54 T1: 55 T1: 56 T1: 57 T1: 58 T1: 59 T1: 60 T1: 61 T1: 62 T1: 63 T1: 64 T1: 65 T1: 66 T1: 67 T1: 68 T1: 69 T1: 70 T1: 71 T1: 72 T1: 73 T1: 74 T1: 75 T1: 76 T1: 77 T1: 78 T1: 79 T1: 80 T1: 81 T1: 82 T1: 83 T1: 84 T1: 85 T1: 86 T1: 87 T1: 88 T1: 89 T1: 90 T1: 91 T1: 92 T1: 93 T1: 94 T1: 95 T1: 96 T1: 97 T1: 98 T1: 99 ------T2: 54 ------T2: 55 ------T2: 56 ------T2: 57 ------T2: 58 ------T2: 59 ------T2: 60 ------T2: 61 ------T2: 62 ------T2: 63 ------T2: 64 ------T2: 65 ------T2: 66 ------T2: 67 ------T2: 68 ------T2: 69 ------T2: 70 ------T2: 71 ------T2: 72 ------T2: 73 ------T2: 74 ------T2: 75 ------T2: 76 ------T2: 77 ------T2: 78 ------T2: 79 ------T2: 80 ------T2: 81 ------T2: 82 ------T2: 83 ------T2: 84 ------T2: 85 ------T2: 86 ------T2: 87 ------T2: 88 ------T2: 89 ------T2: 90 ------T2: 91 ------T2: 92 ------T2: 93 ------T2: 94 ------T2: 95 ------T2: 96 ------T2: 97 ------T2: 98 ------T2: 99
正常停止线程
public class ThreadStop { public static void main(String[] args) { Runner3 r = new Runner3(); Thread t = new Thread(r); t.start(); for (int i = 0; i < 10; i++ ) { if (i % 10 == 0 & i > 0) { System.out.println("in thread main i=" + i); } System.out.println("thread main is over"); r.shutDown(); } } } class Runner3 implements Runnable { private boolean flag = true; public void run() { int i = 0; while (flag == true) { System.out.println(" " + i++); } } public void shutDown() { flag = false; } }
输出结果
Compiling ThreadStop.java....... -----------OUTPUT----------- thread main is over 0 thread main is over thread main is over thread main is over thread main is over thread main is over thread main is over thread main is over thread main is over thread main is over
wait()/notify()
public class TestWait extends Thread { public TestWait(String name) { super(name); } public void run() { for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName() + " : " + i); } } public static void main(String[] args) throws InterruptedException { Thread t1 = new TestWait("t1"); Thread t2 = new TestWait("t2"); t1.start(); synchronized (t1) { t1.wait(10); } t2.start(); synchronized (t1) { t1.notify(); } } }
输出结果:
Compiling TestWait.java....... -----------OUTPUT----------- t1 : 0 t1 : 1 t1 : 2 t1 : 3 t1 : 4 t1 : 5 t1 : 6 t1 : 7 t1 : 8 t1 : 9 t2 : 0 t2 : 1 t2 : 2 t2 : 3 t2 : 4 t2 : 5 t2 : 6 t2 : 7 t2 : 8 t2 : 9
sleep() VS wait()
sleep()方法和wait()方法都可以使得线程暂停等待,那么究竟它们有什么共同点呢?有什么区别呢?
共同点:
1>都是在多线程的环境下,都能够使得线程暂停等待一定的时间;
2>都可以使用interrupt()打断线程的等待状态,但是会使得线程对象立即抛出InterruptedException错误
区别:
1>来源不同,sleep()是在Thread类中定义的,而wait()是Object类定义的;
2>wait()方法只能在同步块中使用,而sleep()可以在任何地方使用;
3>使用sleep()方法的时候必须捕捉异常,而wait()方法不用;
4>调用sleep()方法并不会释放锁,睡眠期间,其他线程也无法访问这个对象;而wait()方法会释放锁(暂时的释放),等待期间,其他线程可以访问这个对象