程序:一组实现某些特定功能的代码的集合体,此时没有运行。
进程:正在运行的这段代码,体现此时已经运行。
线程:是同一个进程下,同时开始的多个任务。
每个Java程序都有一个隐含的主线程:main方法
何时需要多线程
1、程序需要同时执行两个或多个任务。
2、程序需要实现一些需要等待的任务时,如用户输入、文件读写操作、网络操作、搜索等。
3、需要一些后台运行的程序时。
创建多线程的第一种方式:
package com.umpay.thread;
//第一种实现多线程的方式
public class MyThreadOne extends Thread {
//需要我们使用多线程运行的代码就写在run方法里。
@Override
public void run() {
// TODO Auto-generated method stub
for(int i=1;i<=100;i++){
//Thread.currentThread().getName()获取当前正在运行的线程名
System.out.println(Thread.currentThread().getName()+"线程正在运行~~~~~"+i);
}
}
}
package com.umpay.thread;
public class TestOne {
public static void main(String[] args) {
// TODO Auto-generated method stub
MyThreadOne mto = new MyThreadOne();
mto.start();
for(int i=1;i<=100;i++){
System.out.println(Thread.currentThread().getName()+"线程正在运行=========="+i);
}
}
}
/*
* 本类用于演示使用继承Thread类的方式实现的多线程
* 三个窗口同时卖票,一共100张,票卖完就退出
*/
public class ShellTicketOne extends Thread {
private static int ticket = 100;
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
if(ticket <= 0){
System.out.println("票已卖完================,退出");
break;
}
System.out.println(Thread.currentThread().getName()+"售票窗口卖出一张票~~~~~~~~~~~~~~~~~当前还剩余:"+(--ticket));
}
}
}
/*
* 本类用于演示第二种实现Runnable接口的方式多线程
* 三个窗口卖100张票,卖完退出
* 实现Runnable接口的方式由于开启多线程的时候创建的多个Thread对象,所以只需要一个自定义线程类对象,
* 那么这个自定义线程类对象的普通属性就可以被多个线程同时方法。所以我们说实现Runnable接口的方式更适合多个线程访问同一个数据。
*/
public class ShellTicketTwo implements Runnable {
private int ticket = 100;
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
if(ticket <= 0){
System.out.println("票已卖完================,退出");
break;
}
System.out.println(Thread.currentThread().getName()+"售票窗口卖出一张票~~~~~~~~~~~~~~~~~当前还剩余:"+(--ticket));
}
}
}
public class TestShellTicketOne {
public static void main(String[] args) {
// TODO Auto-generated method stub
ShellTicketOne one = new ShellTicketOne();
ShellTicketOne two = new ShellTicketOne();
ShellTicketOne three = new ShellTicketOne();
one.start();
two.start();
three.start();
}
}
public class TestShellTIcketTwo {
public static void main(String[] args) {
// TODO Auto-generated method stub
ShellTicketTwo st = new ShellTicketTwo();
new Thread(st).start();
new Thread(st).start();
new Thread(st).start();
}
}
/*
* 本类用于测试第二种创建和调用多线程的方式
* 由于Runnable接口只有run一个方法,所以实现Runnable接口的这种方式,线程类本身没有start方法。
* 但是必须要调用start方法才能开启多线程,所以需要创建Thread类的对象,把我们的线程类作为参数传递给构造方法。
* 当传参创建出来的Thread对象去调用start方法的时候,运行的是参数这类的run方法。
*/
public class TestTwo {
public static void main(String[] args) {
// TODO Auto-generated method stub
MyThreadTwo mtt = new MyThreadTwo();
//创建Thread对象的时候需要我们自己定义的这个实现了Runnable接口的线程类作为参数。
Thread thread = new Thread(mtt);
thread.start();
for(int i=0;i<=100;i++){
System.out.println(Thread.currentThread().getName()+"线程正在运行============"+i);
}
}
}
3.线程的停止
1、当线程正常运行结束,完成所有代码后,线程停止。一个线程一旦停止就消失了,不能重复开启。
2、在线程方法运行某一个时候,由外界向它发送了一个停止的通知,这个线程停止。
3、当线程中代码出现异常或者其他错误的时候,线程停止。
4、调用Thread的stop()方法可以停止一个线程,但是这个方法已经过时,并且不再建议使用。
/*
* 本类用于演示通过通知的方式停止一个线程
*/
public class TestStopThread {
public static void main(String[] args) {
// TODO Auto-generated method stub
MyStopThread mtt = new MyStopThread();
mtt.start();
for(int i=0;i<100;i++){
if(i==35){
//通知的方式停止线程
System.out.println("发送停止通知,停止一个线程");
mtt.setFlag(false);
//break;
}
System.out.println("main线程中的代码~~~~~~~~~~~~~~~~~~"+i);
}
}
}
class MyStopThread extends Thread{
private boolean flag = true;
public boolean isFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(flag){
System.out.println("演示通知方式退出一个线程~~~~~~~~~~~~~~~~~~~~~~~~");
}
}
}