先认识什么是线程:重点内容
1、程序:一堆指令组合在一起,程序。 应用程序 ,后台程序。
2、 进程:就是程序打开之后,内存空间中运行。每次打开一个进程的时候,所消耗的资源非常大的。
3、线程:线程就是运行在进程中的程序流,每个进程内部都可以现实多线程。
Java 虚拟机允许应用程序并发地运行多个执行线程。
进程内部,这个进程里面的资源都可以被每个线程所共享。
4、多线程:在一个程序中运行多个任务
目的是更好地使用CPU资源
并行: 真正意义上的 同一个时间,进行不同的操作
并发
高并发: 看着是同一个时间,进行不同的操作。
每个线程都有一个优先级,高优先级线程的执行优先于低优先级线程。每个线程都可以或不可以标记为一个守护程序。当某个线程中运行的代码创建一个新 Thread 对象时,该新线程的初始优先级被设定为创建线程的优先级,并且当且仅当创建线程是守护线程时,新线程才是守护程序。
如何现实线程的?
时间碎片的概念完成多线程。每个现在由每个时间碎片不停的切换操作
线程的实现
一、继承Thread类
/**
* 线程的创建:方法一:
继承Thread,重写父类的run方法。
* @author Administrator
*
*/
public class MyThread extends Thread {
// private static int num = 0;
//
// public MyThread() {
// num++;
// }
//
// public void run() {
// System.out.println("第 " + num + "个线程");
// }
private String name;
public MyThread(String name){
this.name=name;
}
public void run(){
System.out.println("name= "+name+"\t子线程ID\t:"+Thread.currentThread().getId());
}
}
这是我们测试的吧
public class Test {
public static void main(String[] args) {
//currentThread() 返回对当前正在执行的线程对象的引用。
//getId() 返回该线程的标识符。
System.out.println("主线程:"+Thread.currentThread());
System.out.println("主线程ID:"+Thread.currentThread().getId());
System.out.println("主线程名字:"+Thread.currentThread().getName());
System.out.println("返回线程的优先级:"+Thread.currentThread().getPriority());
System.out.println("返回一个表示该线程堆栈转储的堆栈跟踪元素数组:"+Thread.currentThread().getStackTrace());
System.out.println("该线程状态:"+Thread.currentThread().getState());
System.out.println("该线程所属的线程组。:"+Thread.currentThread().getThreadGroup());
MyThread mt = new MyThread("start");
mt.start();//启动线程
MyThread mt2 = new MyThread("run");
mt2.run();//相当于在主线程中执行run方法,不会创建新的线程
}
/**
* 看控制台输出,run 和 start 的子线程ID是不相同的,二run和主线程的ID相同。
* 说明用run()方法调用并不会创建一个新的线程,它只是调用了主线程的run
*
* 而用start()方法启动线程,就创建了 一个新的线程。
* 还有我们先调用的是Start()方法,但是输出的时候是先输出run()方法调用的相关信息
* 说明新线程的创建不会阻碍主线程的执行
*
*/
}
控制台输出:
主线程:Thread[main,5,main]
主线程ID:1
主线程名字:main
返回线程的优先级:5
返回一个表示该线程堆栈转储的堆栈跟踪元素数组:[Ljava.lang.StackTraceElement;@15db9742
该线程状态:RUNNABLE
该线程所属的线程组。:java.lang.ThreadGroup[name=main,maxpri=10]
name= run 子线程ID :1
name= start 子线程ID :11
二、实现Runnable接口
设计该接口的目的是为希望在活动时执行代码的对象提供一个公共协议。例如,Thread 类实现了 Runnable。激活的意思是说某个线程已启动并且尚未停止。
此外,Runnable 为非 Thread 子类的类提供了一种激活方式。通过实例化某个 Thread 实例并将自身作为运行目标,就可以运行实现 Runnable 的类而无需创建 Thread 的子类。大多数情况下,如果只想重写 run() 方法,而不重写其他 Thread 方法,那么应使用 Runnable 接口。这很重要,因为除非程序员打算修改或增强类的基本行为,否则不应为该类创建子类。
/**
* 线程创建方法2 实现Runnable接口,并且实现接口里面的run()方法。 实现Runnable接口,不是你就是线程类,你这个类只是一个需要使用线程的类
*
* @author Administrator
*
* Runnable 中文意思是 任务
*/
public class RunnableTest implements Runnable {
//构造方法
public RunnableTest() {
// TODO Auto-generated constructor stub
}
//实现Runnable里的方法
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("子线程ID:"+Thread.currentThread().getId());
}
}
public class Test2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("主线程ID"+Thread.currentThread().getId());
//实例化RunnableTest对象
RunnableTest rt = new RunnableTest();
//吧rt交给Therad去执行
Thread thread = new Thread(rt);
RunnableTest rt2 = new RunnableTest();
Thread thread2 = new Thread(rt2);
thread.start();
thread2.run();
}
}
介绍一下线程的状态:
new(创建):已经准备好了一个可执行的多线程对象
runnable(就绪,可运行):调用start()方法,等待CPU调用
running(运行):执行run()方法
blocked(阻塞):暂时停止执行,将资源交给其他线程使用
在这里面阻塞用几种:等待、锁定
dead(死亡):线程销毁
观察图种的Thread方法:
start(); 使该线程开始执行;Java 虚拟机调用该线程的 run 方法。
join(); 等待该线程终止。
sleep(); 在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。
yield();暂停当前正在执行的线程对象,并执行其他线程。
wait();在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。
notify();唤醒在此对象监视器上等待的单个线程。
notifyAll(); 唤醒在此对象监视器上等待的所有线程。
interrupt();中断线程
run();如果该线程是使用独立的 Runnable 运行对象构造的,则调用该 Runnable 对象的 run 方法;否则,该方法不执行任何操作并返回。
wait()暂停当前线程后,需要别的线程执行notify()来唤醒它。
同步锁(Synchronized)