1、程序、进程、线程的区别:
1)程序:程序员使用代码所编写的,用于实现一定的代码的指令或者集合,称作程序。
2)进程:启动的程序,称作进程
进程的三要素:CPU,data,code
每个进程之间是相互独立的,一个进程的结束,不会影响其他的进程
进程与进程之间的切换效率低,一个进程至少有一个线程,负责具体的业务执行
3)线程:线程是进程的组成部分,用于执行
一个进程中,由N多个线程组成,这N多个线程之间共享一块内存,线程之间的切换效率高
2、java中实现线程的方法有两种:
1)新写的Thread线程继承Thread类
①Thread线程要继承Thread线程
②在主类主方法中要进行启动my.start(),线程启动是start(),而不是对象名.方法名
③应用举例:
package com.wyq.thread;
public class MyThread extends Thread{
@Override
public void run() {
for(int i = 0;i<=5;i++){
//Thread.curentThread()用于获取当前线程的对象,getName(),用于获取线程名称
System.out.println(Thread.currentThread().getName()+"Thread线程中的方法——————>"+i);
}
}
}
主线程类:
package com.wyq.thread;
public class TestThread {
public static void main(String[] args) {
//创建线程类对象
MyThread my = new MyThread();
//线程启动
my.start();
//主线程中的循环
for(int i = 0;i<=5;i++){
System.out.println("主线程中的方法——————>"+Thread.currentThread().getName()+"————>"+i);
}
}
}
④线程运行图示说明
2)实现runnable接口
①在线程类中实现Runnable接口
②调用运行
③调用start()方法启动
④代码:
package com.wyq.thread;
public class MyThread2 implements Runnable{
@Override
public void run() {
for(int i = 0;i<=5;i++){
System.out.println(Thread.currentThread().getName()+"——————>"+i);
}
}
}
只要类中的方法
package com.wyq.thread;
public class TestThread2 {
public static void main(String[] args) {
//创建线程类对象
MyThread my = new MyThread();
//线程启动
// my.start();
Thread t = new Thread(my);
t.start();
//主方法中的循环
for(int i = 0;i<=5;i++){
System.out.println(Thread.currentThread().getName()+"++++++++》"+i);
}
}
}
以上这种是静态代理设计模式
⑤API分析
⑥代理设计模式图示
⑦源码分析:
3、继承不实现资源共享的方式
package com.wyq.thread;
public class MyThread3 extends Thread{
public MyThread3(String threadName){
super(threadName);//调用父类Thread类中带参的构造方法
}
private int ticket = 5;//5张票
@Override
public void run() {
for(int i =0;i<100;i++){
if(ticket>0){
System.out.println(Thread.currentThread().getName()+"在买第"+(ticket--)+"张票。");
}
}
}
}
测试类
package com.wyq.thread;
public class TestThread3 {
public static void main(String[] args) {
//创建线程类的对象
MyThread3 my1= new MyThread3("A窗口");
MyThread3 my2= new MyThread3("B窗口");
MyThread3 my3= new MyThread3("C窗口");
//同时进行
my1.start();
my2.start();
my3.start();
}
}
图示说明
4、实现资源共享的方式
package com.wyq.thread;
public class MyThread4 implements Runnable{
private int ticket = 5;
@Override
public void run() {
for(int i = 0;i<4;i++){
if(ticket>0){
System.out.println(Thread.currentThread().getName()+"正在卖第"+i+"张票");
}
}
}
}
测试类
package com.wyq.thread;
public class TestThread4 {
public static void main(String[] args) {
//创建线程类对象
MyThread4 my = new MyThread4();
//创建三个代理类
Thread t1 =new Thread(my,"A窗口");
Thread t2 = new Thread(my, "B窗口");
Thread t3 = new Thread(my,"C窗口");
//启动线程
t1.start();
t2.start();
t3.start();
}
}
图示解释
5、线程的声明周期
6、 线程的状态:
首先你不知道什么时候会被挑中执行(就绪状态);
第二,在执行的过程中随时可能被打断(时间片到了),让出CPU车间(就绪);
第三,一旦出现硬盘、数据库这样耗时的操作,也得让出CPU去等待(阻塞);
第四,就是数据来了,你也不一定马上执行,还得等着(就绪)CPU挑选
线程(正常) 就绪<--->运行
(等待资源) 运行-->阻塞状态-->就绪-->运行状态
7、线程中的先关操作方法
1)currentThread属性
package com.wyq.thread;
public class TestThread5 {
public static void main(String[] args) {
Thread t = Thread.currentThread();
System.out.println(t);
System.out.println(t.toString());
/**
* Thread[main,5,main]
* currentThread对应的是main主线称
* getName()线程额名称
* getPriority()线程的优先级
* group.getName线程组的名称
*/
MyThread my = new MyThread();
System.out.println(my);
/**
* Thread-0:线程的名称
* 5:线程的优先级
* main:线程组的名称
*/
ThreadGroup tg = new ThreadGroup("线程组A");//创建了一个线程组
//Thread线程了中的带参构造方法
Thread tt = new Thread(tg,my);
System.out.println(tt);
/**
* Thread[Thread-1,5,线程组A】
* Thread-1:线程的名称
* 5:优先级
* 线程组A:线程组的名称
*/
}
}
2)线程的优先级以及线程的名称
package com.wyq.thread;
public class TestPriority {
public static void main(String[] args) {
//获取当前线程
Thread t = Thread.currentThread();
System.out.println(t);
System.out.println("赋值之前线程的名称"+t.getName());
t.setName("A线程");
t.setPriority(Thread.MAX_PRIORITY);
System.out.println(t);
System.out.println("最小优先级:"+Thread.MIN_PRIORITY);
System.out.println("最大优先级:"+Thread.MAX_PRIORITY);
System.out.println("默认优先级:"+Thread.NORM_PRIORITY);
System.out.println("线程的名称:"+t.getName());
System.out.println("赋值之前线程的优先级:"+t.getPriority());
t.setPriority(1);
//获取当前线程的优先级
System.out.println("当前线程的优先级:"+t.getPriority());
}
}
3)sleep方法
package com.wyq.thread;
public class MyThread2 implements Runnable{
@Override
public void run() {
System.out.println("1.系统进行run方法");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("2.系统休眠中");
}
}
测试类
package com.wyq.thread;
public class TestThread2 {
public static void main(String[] args) {
//创建线程类对象
MyThread2 my = new MyThread2();
//线程启动
// my.start();
Thread t = new Thread(my);
t.start();
//主方法中的循环
for(int i = 0;i<=5;i++){
System.out.println(Thread.currentThread().getName()+"++++++++》"+i);
}
}
}
4)isAlive()判断线程是否处于活跃状态
package com.wyq.thread;
public class MyThread extends Thread{
@Override
public void run() {
for(int i = 0;i<=5;i++){
//Thread.curentThread()用于获取当前线程的对象,getName(),用于获取线程名称
System.out.println(Thread.currentThread().getName()+"Thread线程中的方法——————>"+i);
}
}
}
测试类
package com.wyq.thread;
public class TestIsAlive {
public static void main(String[] args) {
//创建线程类对象
MyThread my = new MyThread();//新生状态
System.out.println("新生状态:"+my.isAlive());
my.start();
System.out.println("启动之后:"+my.isAlive());
//主线程中的代码
for(int i = 0;i<10;i++){
System.out.println(Thread.currentThread().getName()+"+++++++++++++》"+i);
}
System.out.println("主线程结束:"+my.isAlive());
}
}
5)join(),实际上,调用join这个方法,该线程强制执行,而主线程处于阻塞状态
package com.wyq.thread;
public class MyThread extends Thread{
@Override
public void run() {
for(int i = 0;i<=5;i++){
//Thread.curentThread()用于获取当前线程的对象,getName(),用于获取线程名称
System.out.println(Thread.currentThread().getName()+"Thread线程中的方法——————>"+i);
}
}
}
测试类
package com.wyq.thread;
public class TestJoin {
public static void main(String[] args) throws InterruptedException {
//创建一个线程类对象
MyThread my = new MyThread();
//启动线程
my.start();
//主线程
for(int i =0;i<10;i++){
//这里 是主线程
if(i==4){
//my这个线程强制执行,主线程阻塞
//这里调用的是my这个线程
my.join();
}
System.out.println(Thread.currentThread().getName()+"++++++>"+i);
}
/**
* 实际上是当i=2的时候,主线程等不执行,等待my这个线程先执行
*/
}
}
6)yield()让步,是指调用该方法之后,该方法会让步,而另一种方法会执行
在这种情况下,效果可能不是很明显,原因是主线程做了让步,但是在让步的过程中,其他的线程未必就执行了
package com.wyq.thread;
public class MyThread extends Thread{
@Override
public void run() {
for(int i = 0;i<=5;i++){
//Thread.curentThread()用于获取当前线程的对象,getName(),用于获取线程名称
System.out.println(Thread.currentThread().getName()+"Thread线程中的方法——————>"+i);
}
}
}
测试类:
package com.wyq.thread;
public class TestYield {
public static void main(String[] args) {
//创建线程类对象
MyThread my = new MyThread();
//启动线程
my.start();
//主线程中的代码
for(int i = 0;i<10;i++){
System.out.println("主线程让步前:"+Thread.currentThread().getName()+"+++++》"+i);
if(i==3){
//这里是主线程在让步
Thread.yield();
System.out.println("主线程让步结束。。");
}
System.out.println("主线程让步之后:"+Thread.currentThread().getName()+"+++++》"+i);
}
}
}