黑马程序员————多线程

来源:互联网 发布:淘宝客优惠券推广 编辑:程序博客网 时间:2024/06/05 23:58

概述

一:进程

​正在执行中的程序,每一个进程执行都有一个执行顺序。该顺序是一个执行路径,或者叫一个控制单元。

二:线程

进程中的一个独立的控制单元。线程在控制着进程的执行。一个进程中至少有一个线程。只要进程中有一个线程在执行,进程就不会结束。​

三:多线程

​在java虚拟机启动的时候会有一个java.exe的执行程序,也就是一个进程。该进程中至少有一个线程负责java程序的执行。而且这个线程运行的代码存在于main方法中。该线程称之为主线程。JVM启动除了执行一个主线程,还有负责垃圾回收机制的线程。这种在一个进程中有多个线程执行的方式,就叫做多线程。

创建方式

创建线程共有两种方式:继承方式和实现方式。​

一:继承方式

Java API文档的java.lang包中提供了Thread类,通过继承Thread类,然后覆写其run方法来创建线程。​

步骤为:定义一个类并继承Thread类

​              覆写run方法

              调用start方法启动线程。

运用实例:​

public class MyThread extends Thread{


@Override
public void run() {
//将需要在此独立线程中执行的代码写到这里
for(int i = 0;i < 100;i++){
System.out.println("Hello i = " + i);
}
}

}

public class Demo {
public static void main(String[] args) {
MyThread t = new MyThread();
t.start();//启动线程;

for(int i = 0 ;i <100 ; i++){
System.out.println("main i = " + i);
}
}
}

二:实现方式

创建步骤:定义类实现Runnable接口

                覆盖Runnable接口中的run方法。​

                通过Thread类创建线程对象。

                将Runnable接口的子类对象作为实参传递给Thread类的构造方法。​

                调用Thread类中start方法启动线程,start方法会自动调用Runnable接口子类的run方法。

继承方式和实现方式的区别:

继承方式:线程代码存放在Thread子类的run方法中。​

实现方式:线程代码存在接口的子类run方法中。

运用实例(售票示例):

/*
 * 票池类
 */
public class TicketPool {
private int ticketNum = 100;//ticketNum = 1;

public int getTicket(){//t1,t2,t3

if(ticketNum > 0){//t1进入
//此处模拟执行一些其他操作,会消耗一些时间。目的是让其它线程有机会进来抢占
try {
Thread.sleep(5);//t1睡眠,t2进入,t2也睡,t3进入,t3也睡
} catch (InterruptedException e) {
e.printStackTrace();
}
//由于此方法会被多个线程同时访问,在ticketNum--时,此操作不具有原子性;
//这种操作由一系列指令组成;当多个线程并发访问时,会造成数据不一致的问题;
return this.ticketNum--;//t1取走1,ticketNum= 0;t2取走0,ticketNum = -1;t3取走-1,ticketNum = -2
}else{
return 0;
}
}
}

public class SellTicketRunnable implements Runnable {
private TicketPool pool;
private TreeSet<Integer> set = new TreeSet<>();

public SellTicketRunnable(TicketPool p){
this.pool = p;
}
@Override
public void run() {
// 一直取票直到取到0为止
while (true) {
int n = this.pool.getTicket();
if (n != 0) {
System.out.println("取到票:" + n);
set.add(n);
} else {
System.out.println("票被抢光了!");
break;
}
}
System.out.println(Thread.currentThread().getName() + "抢到票:" + set.size() + " 张 : " + set);
}


}

public class Demo {
public static void main(String[] args) {
TicketPool pool = new TicketPool();

SellTicketRunnable myRun1 = new SellTicketRunnable(pool);
SellTicketRunnable myRun2 = new SellTicketRunnable(pool);
SellTicketRunnable myRun3 = new SellTicketRunnable(pool);

Thread t1 = new Thread(myRun1);
Thread t2 = new Thread(myRun2);
Thread t3 = new Thread(myRun3);

t1.setName("窗口1");
t2.setName("窗口2");
t3.setName("窗口3");

t1.start();
t2.start();
t3.start();


}
}



0 0
原创粉丝点击