多线程并发就像是内功,框架都像是外功,内功不足,外功也难得精要.
1.进程和线程的区别
一个程序至少有一个进程,一个进程至少有一个线程.
用工厂来比喻就是,一个工厂可以生产不同种类的产品,操作系统就是工厂,产品就是进程,工人就是线程.
工厂----->操作系统
产品----->进程
工人---->线程
一个工厂可以同时生产不同的产品,即多个产品可以同时进行生产;
一种产品可以由多个工人协同工作,同样可以同时进行;
对应到操作系统的设计,因此可以归结为三点:
(1)以多进程形式,允许多个任务同时运行;
(2)以多线程形式,允许单个任务分成不同的部分运行;
(3)提供协调机制,一方面防止进程之间和线程之间产生冲突,另一方面允许进程之间和线程之间共享资源。
2.并发(concurrency)和并行(Parallel)的区别
并发和并行的区别是一个处理器同时处理多个任务和多个处理器或者是多核的处理器同时处理多个不同的任务.
比喻:并发和并行的区别就是一个人同时吃三个馒头和三个人同时吃三个馒头。
3.创建线程有哪几种方式?
1)创建线程方式一: 继承Thread类
子类覆盖父类中的run方法,将线程运行的代码存放在run中。
建立子类对象的同时线程也被创建。
通过调用start方法开启线程。
2)创建线程方式二: 实现Runnable接口
子类覆盖接口中的run方法。
通过Thread类创建线程,并将实现了Runnable接口的子类对象作为参数传递给Thread类的构造函数。
Thread类对象调用start方法开启线程。
public static void main(String[] args) { //方式1: Thread thread = new Thread(){ @Override public void run() { while(true){ try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("1:"+Thread.currentThread().getName()); } } }; thread.start(); //方式2: Thread thread2 = new Thread(new Runnable() { public void run() { while(true){ try { Thread.sleep(500); } catch (Exception e) { e.printStackTrace(); } System.out.println("2:"+Thread.currentThread().getName()); } } }); thread2.start(); }
4.线程的四种状态
线程有四种状态,任何一个线程肯定处于这四种状态中的一种:
1) 被创建或新建(New):线程对象已经产生,但尚未被启动,所以无法执行。如通过new产生了一个线程对象后没对它调用start()函数之前。
2) 运行或可执行(Runnable):每个支持多线程的系统都有一个排程器,排程器会从线程池中选择一个线程并启动它。当一个线程处于可执行状态时,表示它可能正处于线程池中等待排排程器启动它;也可能它已正在执行。如执行了一个线程对象的start()方法后,线程就处于可执行状态,但显而易见的是此时线程不一定正在执行中。
3) 消亡或死亡(Dead):当一个线程正常结束,它便处于死亡状态。如一个线程的run()函数执行完毕后线程就进入死亡状态。
4) 冻结或停滞(Blocked):当一个线程处于停滞状态时,系统排程器就会忽略它,不对它进行排程。当处于停滞状态的线程重新回到可执行状态时,它有可能重新执行。如通过对一个线程调用wait()函数后,线程就进入停滞状态,只有当两次对该线程调用notify或notifyAll后它才能两次回到可执行状态。
5.线程中的计时器
计时器主要用于任务管理,在线程控制中占有很重要的地位,需要掌握.
1)第一次是在1秒后启动,然后每隔3秒循环启动一次
package com.amos.concurrent; import java.util.Date; import java.util.Timer; import java.util.TimerTask; /** * @ClassName: TraditionalTimerTest * @Description: 传统的线程计时器 * @author: amosli * @email:hi_amos@outlook.com * @date Apr 17, 2014 12:54:32 AM */ public class TraditionalTimerTest { public static void main(String[] args) { new Timer().schedule(new TimerTask() { @Override public void run() { System.out.println("timer..."); } }, 1000, 3000); while (true) { System.out.println(new Date().getSeconds()); try { Thread.sleep(1000); System.out.println("1000ms"); } catch (InterruptedException e) { } } } }
运行效果:
35 timer... 1000ms 36 1000ms 37 1000ms 38 timer...
2)每隔2秒每隔4秒间隔运行
package com.amos.concurrent; import java.util.Date; import java.util.Timer; import java.util.TimerTask; /** * @ClassName: TraditionalTimerTest * @Description: 传统的线程计时器 * @author: amosli * @email:hi_amos@outlook.com * @date Apr 17, 2014 12:54:32 AM */ public class TraditionalTimerTest { private static int count = 0 ; @SuppressWarnings("deprecation") public static void main(String[] args) { //间隔2秒和4秒分开运行 class myTimerTask extends TimerTask{ @Override public void run() { count = (count+1)%2; if(count==1){ System.out.println("mybombing_2000...."); new Timer().schedule(new myTimerTask(), 2000); }else { System.out.println("mybombing_4000...."); new Timer().schedule(new myTimerTask(), 4000); } } } new Timer().schedule(new TimerTask() { @Override public void run() { new Timer().schedule(new myTimerTask(), 2000); } }, 2000); //输出时间 while (true) { System.out.println(new Date().getSeconds()); try { Thread.sleep(1000); } catch (InterruptedException e) { } } } }
运行效果:
22 23 24 25 mybombing_2000.... 26 27 mybombing_4000.... 28 29 30 31 mybombing_2000.... 32 33 mybombing_4000.... 34 35 36 37
计时器的实现主要采用的是Timer类的.schedule()方法,默认的.schedule()方法中传入的是void java.util.Timer.schedule(TimerTask task, long delay),一个task,一个是延时操作;比较常用的是void java.util.Timer.sched(TimerTask task, long time, long period),period表示的是每隔一定时间进行循环执行task;当然这里还有定时操作void java.util.Timer.schedule(TimerTask task, Date time),这里要按实际需求去选择了.