多线程:
进程:正在运行的程序,为程序运行的线程开辟空间,管理线程。
线程:程序运行的单元,一条执行路径。
多线程是为了解决某个任务执行会延缓别的任务执行。干脆多线程执行。
JVM:
主线程,GC线程。
主线程定义在了main函数中。
程序中常常需要多个任务同时执行,可以创建多个线程来分别执行。
创建线程的两种方式:
1:继承Thread类,重写run方法,使用start方法启动线程(jvm会自动调用run方法)。
继承Thread后本质上这个类属于线程体系(Java不支持多继承。。。)
任务代码写在run方法中。
run方法就是封装需要运行的代码的函数。开启多线程就是为了运行指定的代码。
2:实现Runable接口,覆盖接口中的run方法(任务方法),有参构造线程,start方法开启。
Runable接口只是将run方法封装,有参构造Thread类传入run的封装。
避免单继承局限,将线程任务封装。
被封装后的run方法中的数据可以共享于多个线程。
##多线程的三种实现:http://blog.csdn.net/shenggaofei/article/details/52643137
##callAble和Future:http://blog.csdn.net/ghsau/article/details/7451464
1 package demo; 2 import java.util.concurrent.Callable; 3 import java.util.concurrent.ExecutionException; 4 import java.util.concurrent.FutureTask; 5 //callAble和FutureTask的使用demo 6 public class Demo { 7 public static void main(String[] args) throws InterruptedException, ExecutionException { 8 Callable<String> callable = new Callable<String>(){ 9 @Override 10 public String call() throws Exception { 11 MyData myData = new MyData(); 12 return myData.toString(); 13 } 14 }; 15 FutureTask<String> futureTask = new FutureTask<String>(callable); 16 new Thread(futureTask).start(); 17 System.out.println("futureTash中的CallAble返回的数据是:"+futureTask.get().toString()); 18 } 19 static class MyData{ 20 public String name = "lixuming"; 21 public int age = 27; 22 @Override 23 public String toString() { 24 return name+age; 25 } 26 } 27 }
线程内存:
每一个线程都会有自己的一个栈区,CPU在不同的栈区中快速切换。
某个线程发生异常,则这个线程结束,但是别的线程不会结束。
线程状态:
运行----(run方法结束)-----消亡
运行----(sleep(时间))-----冻结------(时间到)-------运行或者阻塞
运行----(wait())--------冻结------(modefy())-----运行或者阻塞
阻塞----(CPU处理队列中排队)------运行
冻结 放弃执行权和执行资格(不在CPU切换的范围内,队列之外。。。) 只有在运行状态才可以冻结
阻塞 等待CPU执行(排队中。。。)
需要注意多线程的安全问题。
多个线程操作共享数据,操作代码大于1条。
同步的表现形式:
同步代码块:
synchronized(对象){}
锁 可以是任意对象
同步后效率变低。
同步函数:
synchronized修饰的函数,(当多线程操作的内容为一个函数时,可以将此函数编程同步函数以便以解决线程安全问题)
非静态同步函数的锁是this
静态同步函数的锁是字节码对象:
同步的前 提:
1:多个线程
2:使用同一个锁(注意锁定义的位置,有可能创建在了局部,产生了多个锁)
死锁:
同步的嵌套,互相持有对方的锁。
run(){
if synchronized(锁A){synchronized(锁B){B操作}}
else synchronized(锁B){synchronized(锁A){A操作}}
}
一个线程执行if拿到了A锁,另外一个线程执行else拿到了B锁。
sleep和wait
sleep 不释放锁 时间到恢复
wait 会释放所 notify恢复
停止线程:
1:提供一个标记,判断标记结束run方法。(run方法中含有循环)
2: 3:
------------------------------------------------注意-----------------------------------------------
1:单例模式和线程安全问题
2:生产者消费者问题和线程通信
3:线程的停止问题