------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
一,进程和线程的概念:
要了解"线程",必须先了解一下"进程":
什么是进程:
1.对于"操作系统"而言,每个独立运行的程序就是独立的"进程";
2."操作系统"会分别针对每个"进程"分配一块独立的内存空间;
--什么是多进程:
1."操作系统"可以同时维护多个"应用程序"的执行。
2.每个应用程序都交由操作系统管理,在某个时间点上,会有一个应用程序被操作系统分配给CPU去执行,执行一会后,会被操作系统
终止执行,并交由另一个"应用程序"继续执行。由于转换非常快,CPU的运算速度也非常快,这就让我们感觉好像是多个应用程序在
同时执行一样。
3.多进程的意义:
1).方便了我们用户的使用。我们可以同时启动多个程序,一边听歌,一边上网,一边下载;
2).充分的利用CPU资源;
什么是线程:
1.线程是由一个"进程"的内部启动的,可以脱离于"主进程"而独立运行的一块代码;
2.一个线程一旦启动,将和"主进程"并行运行,一起面对操作系统,抢占系统资源;
3.一个"进程"可以启动多个"线程";
--什么是多线程:
1.一个进程可以同时启动多个线程去单独运行;这个程序就是一个多线程程序;
2.多线程的意义:
1).可以使我们的应用程序"同时"运行多个非常复杂的代码;
2).使我们的程序不用等待那些代码的执行完毕,就可以继续获得执行;
3).充分的利用了CPU的资源;
什么是"并行"和"并发":
1."并行"是指逻辑上一起在执行,它强调的是在"同一段时间内"一起运行的程序;
2."并发"是指物理上的抢占同一资源。它强调的是在"同一时刻时"一起抢占系统的某个共享资源;
二, 实现线程的:
方式一
实现步骤:
1.自定义一个线程类,要继承自Thread;
2.重写Thread中的run()方法;将要在线程中执行的代码写到这里;
3.启动线程:
1).实例化一个我们自定义的线程类;
2).调用它的start()方法;启动线程;
public class Demo {
02. public static void main(String[] args) {
03. MyThread t1 = new MyThread();
04. MyThread t2 = new MyThread();
05.
06. // t1.run();//相当于普通的方法调用,不是启动一个线程
07. // t2.run();//相当于普通的方法调用,不是启动一个线程
08.
09. t1.start();
10. t2.start();
11.
12. for(int i = 0;i < 100;i++){
13. System.out.println("主进程 i = " + i);
14. }
15.
16. //尝试再次启动t1
17. // t1.start();//运行时异常。不能多次调用start(),否则抛出异常:java.lang.IllegalThreadStateException
18. }
19.}
注意:
1.一个线程类,可以实例化多个对象,并分别启动。也就意味着多个线程同时运行;
2.一个线程对象,只能调用一次start,不能重复调用。否则抛出异常:java.lang.IllegalThreadStateException
3.只用调用start()才是启动线程。run()方法内的代码会以一个线程的方式去运行;
一.线程实现方式:
1.继承Thread类;
2.实现Runnable接口;
二.设置获取线程的名称:
getName()和setName(String name);
三.设置获取线程的优先级:
getPriority()和setPriority(int n);
线程的优先级范围:1--10(从低到高)
四.线程的休眠:sleep(long m):休眠到指定的m毫秒后,将自动醒来;
加入:join();
礼让:yield():退回到"就绪状态",可能会被操作系统重新分配;
守护:setDaemon(boolean on):on为true,守护线程。主进程结束,守护线程也结束,但不会立即结束,会有一个小缓冲;
中断:stop()(过时了)
interrupt():线程一定要处于:Object-->wait();Thread-->sleep();Thread--join()三种状态之一时,才能触发此异常;
五.解决并发性问题:
1.使用关键字:synchronized
2.synchronized可以修饰一个代码块:同步代码块
synchronized可以修饰一个方法:同步方法
3.静态的方法可以被synchronized修饰。
静态的方法内部也可以包含synchronized的代码块,但一般锁定是某个类的class对象。
一.JDK5的Lock锁:
Lock lock = ....;
lock.lock();
try{
//需要同步的代码
}finally{
lock.unlock();
}
二.死锁的现象:
见图
三.生产和消费者问题:
1.单生产和单消费;
2.在共享资源中:
1).wait():让访问的线程等待(释放锁)
2).notify()和notifyAll():唤醒;
四.线程组:
1.任何的线程都有一个默认的线程组;
2.可以自行指定线程组:
1).实例化一个线程组;
2).通过Thread的构造方法去指定线程组;
3.可以统一对线程组内的所有线程执行统一操作;
五.线程池:JDK5后出现:
1.Executors类的
public static ExecutorService newCachedThreadPool()
public static ExecutorService newFixedThreadPool(int nThreads)
public static ExecutorService newSingleThreadExecutor()
2.调用ExecutorService的:
Future<?> submit(Runnable task)
<T> Future<T> submit(Callable<T> task)
六.JDK5的多线程的实现方式(多线程实现的方式3)
1.自定义类,实现Callable接口;
2.重写call()方法;(有返回值了)
3.启动:
使用线程组的方式启动线程;
七.定时器:
1.TimersTask(抽象类):定义任务
1).自定义类,继承自TimerTask;
2).重写run()方法;
2.Timer类:
构造方法:Timer();
执行任务:
public void schedule(TimerTask task, long delay):在delay毫秒后执行一次;
public void schedule(TimerTask task,long delay,long period):在delay毫秒后开始执行,并每间隔period毫秒后会重复执行;
八.设计模式:
1.简单工厂模式:
1.定义具体产品类;
2.定义工厂类;
3.在工厂类中提供针对每个产品的get方法,或者提供一个方法获取所有产品;
优点:前端无需直接面对具体的产品,只需要通过工厂获取具体产品就可以;
缺点:每增加一个新产品,都要修改工厂类;
2.工厂方法模式:
1.定义产品的接口;
2.定义工厂的接口;
3.增加一个产品时,定义产品类,实现"产品接口",定义工厂类,实现"工厂接口"。
优点:新增产品时,对原类无需任何修改;
缺点:类太多;
3.单例模式--饿汉式:
class Student{
prviate static Student stu = new Student();
private Student(){
}
public static Student getStudent(){
return stu;
}
}
4.单例模式--懒汉式:
class Student{
private static Student stu = null;
private Student(){
}
public synchronized static Student getStudent(){
if(stu == null){
stu = new Student();
}
return stu;
}
}
package com.heima.exam;
class StopThreadTest {
public static void main(String[] args) {
ThreadInStop t1 = new ThreadInStop();
t1.start();
int index = 0;
while(true) {
if(index++ == 500){
t1.stopThread();
t1.interrupt();
break;
}
System.out.println(Thread.currentThread().getName());
}
System.out.println("main() exit");
}
}
class ThreadInStop extends Thread {
private boolean bStop = false;
public synchronized void run() {
while(!bStop) {
try {
wait();
} catch(InterruptedException e) {
if(bStop) {
return;
}
}
System.out.println(getName());
}
}
public void stopThread() {
bStop = true;
}
}