1. 线程的状态变化
1
| Thread thread = new Thread();
|
运行状态
当就绪状态被调用并获得处理器资源时,线程就进入了运行状态。自动调用该线程对象的run()方法。run()方法定义该线程的操作和功能
阻塞状态
一个正在执行的线程再某特殊的情况下,如被人为挂起或需要执行耗时的操作,会让CPU暂时中止自己的执行,进入阻塞状态。再可执行状态下,如果调用sleep(),susoend(),wait()等方法,线程都将进入阻塞状态,发生阻塞时线程不能进入排队队列,只有当引起阻塞的原因被消除后,线程才可以转入就绪状态。
死亡状态
线程调用stop()方法时或run()方法执行结束后,即处于死亡状态。处于死亡状态的线程不具有继续运行的能立。
2. 常用方法
强制运行
在线程操作中,可以使用join()方法让一个线程强制运行,线程强制运行期间其他线程无法运行,必须等待此线程完成之后才可以继续执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public class ThreadJoinDemo implements Runnable{ @Override public void run() { for (int i = 0; i < 50; i++) { System.out.println(Thread.currentThread().getName()+"运行,i="+i); } }
public static void main(String[] args) throws InterruptedException { ThreadJoinDemo demo = new ThreadJoinDemo(); Thread thread = new Thread(demo,"线程"); thread.start(); for (int i = 0; i < 50; i++) { if (i>10){ thread.join(); } System.out.println("Main线程运行--->"+i); }
} }
|
线程休眠
在一个程序中允许一个线程进行暂时的休眠,直接使用Thread.sleep()即可实现休眠
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public class ThreadSleepDemo implements Runnable { @Override public void run() { for (int i = 0; i < 50; i++) { try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"运行,i="+i); } } public static void main(String[] args) { ThreadSleepDemo demo = new ThreadSleepDemo(); Thread thread = new Thread(demo,"SleepDemo"); thread.start(); } }
|
中断线程
当一个线程运行时,另外一个线程可以直接通过interrupt()方法中断其运行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| public class ThreadInterruptDemo implements Runnable { @Override public void run() { System.out.println("进入run方法"); try { Thread.sleep(10000); System.out.println("完成休眠"); } catch (InterruptedException e) { System.out.println("休眠被中止"); return; } System.out.println("run方法正常结束"); } public static void main(String[] args) { ThreadInterruptDemo demo = new ThreadInterruptDemo(); Thread thread = new Thread(demo); thread.start(); try { Thread.sleep(20000); } catch (InterruptedException e) { System.out.println("休眠被中止"); } thread.interrupt(); } }
|
后台线程
在Java程序中,只要前台有一个线程在运行,则整个Java进程都不会消失,所以可以设置一个后台线程setDaemon(),这样即使Java线程结束了,此后台线程依然会继续执行,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public class ThreadDaemonDemo implements Runnable { @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println(Thread.currentThread().getName()+":::"+ i ); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args) { ThreadDaemonDemo demo = new ThreadDaemonDemo(); Thread thread = new Thread(demo); thread.setDaemon(true); thread.start(); } }
|
- 线程的优先级
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public class ThreadPriorityDemo implements Runnable { @Override public void run() { System.out.println(Thread.currentThread().getName()+"运行" ); } public static void main(String[] args) { Thread thread1 = new Thread(new ThreadPriorityDemo(),"线程A"); Thread thread2 = new Thread(new ThreadPriorityDemo(),"线程B"); Thread thread3 = new Thread(new ThreadPriorityDemo(),"线程C"); thread1.setPriority(Thread.MIN_PRIORITY); thread2.setPriority(Thread.NORM_PRIORITY); thread3.setPriority(Thread.MAX_PRIORITY); thread1.start(); thread2.start(); thread3.start(); } }
|
3. 同步及死锁
一个多线程的程序如果是通过Runnable接口实现的,则意味着类中的属性被多个线程共享,那么这样就会造成一种问题,如果这个多线程要操作同一个资源时就可能出现资源同步问题
同步代码块
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| public class ThreadSynchronizedDemo implements Runnable { private int ticked = 5; @Override public void run() { for (int i = 0; i < 100; i++) { synchronized (this){ if (ticked>0){ try { Thread.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("卖票:ticked="+ticked--); } } } } public static void main(String[] args) { ThreadSynchronizedDemo demo = new ThreadSynchronizedDemo(); Thread thread1 = new Thread(demo); Thread thread2 = new Thread(demo); Thread thread3 = new Thread(demo); thread1.start(); thread2.start(); thread3.start(); } }
|
同步方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| public class ThreadSynchronizedDemo implements Runnable { private int ticked = 5; @Override public void run() { for (int i = 0; i < 100; i++) { this.setTicked(); } } public synchronized void setTicked(){ if (ticked>0){ try { Thread.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("卖票:ticked="+ticked--); } } public static void main(String[] args) { ThreadSynchronizedDemo demo = new ThreadSynchronizedDemo(); Thread thread1 = new Thread(demo); Thread thread2 = new Thread(demo); Thread thread3 = new Thread(demo); thread1.start(); thread2.start(); thread3.start(); } }
|
死锁
所谓死锁,就是两个线程都在等待对方先完成,造成程序的停滞,一般程序死锁都是在程序运行时出现的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| public class ThreadLockDemo implements Runnable { private static Zhang zhang = new Zhang();
private static Li li = new Li();
private boolean flag = false; @Override public void run() { if (flag) { synchronized (zhang) { zhang.say(); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (li) { zhang.get(); } } } else { synchronized (li) { li.say(); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (zhang) { li.get(); } } } } public static void main(String[] args) { ThreadLockD emo demo1 = new ThreadLockDemo(); ThreadLockD emo demo2 = new ThreadLockDemo(); demo1.flag = true; demo2.flag = false; Thread thread1 = new Thread(demo1); Thread thread2 = new Thread(demo2); thread1.start(); thread2.start(); } } class Zhang{ public void say(){ System.out.println("张三对李四说:“你给我画,我就把书给你。”"); } public void get(){ System.out.println("张三得到了画。"); } } class Li{ public void say(){ System.out.println("李四对张三说:“你给我书,我就把画给你。”"); } public void get(){ System.out.println("李四得到了书。"); } }
|