进程 线程
main 和 run 的区别
Thread
线程运行的状态
Thread 买票
Runnable
main 和 run 的区别
/**
*进程:是一个正在执行的程序
* 每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元.
* (一个进程中个至少有一个线程)
*
*线程: 就是进程中的一个独立的控制单元.
* 线程在控制这进程的执行
*
*JVM 启动的时候会有一个进程.java.exe
* 该进程中至少有一个线程负责java程序的执行,而且这个线程运行的代码存在于main中
* 该线程称为 "主线程",
*扩展: 其实更细节说明JVM,JVM 启动不止一个线程 ,还有一个 负责 "垃圾回收机制" 线程
*
*如何在自定义的代码中,自定义个 线程呢?
* 通过对API的查找,java已经提供了对线程这类事物的描述,即使继承 Thread类
*
*创建线程的第一种方案:继承 Thread.
* 步骤:
* 1.定义类继承Thread.
* 2.复写Thread类中的run方法:目的 将自定义的代码存储在run方法中,让线程运行.
* 3.调用线程对象的start()方法. 该方法有两个作用
* 1.启动线程 2.调用个run()方法
*
*发现运行结果每次都不同,因为多个线程都在获取CPU的执行权,谁就运行.
*明确一点,在某个时刻,只能有一个程序在运行,(多核除外)
*CPU在作者快速的切换,以达到看上去是同时在运行的效果.
*我们可以形象的把多线程的运行行文在互相抢夺CPU的执行权,
*
*这就是 多线程的一个特性:随机性,谁签到谁执行,至于执行多长,CPU说的算.
*
*
*为什么要覆盖run方法呢?
*Thread类用于描述线程.
*该类就定义了一个功能,用于存储线程要运行的代码.该存储功能就是run方法.
*
*run 和 main 的区别
*run():用于存储 Thread中线程要运行的代码
*main():用于存放 "主线程": 要运行的代码;
*
*/
class Demo extends Thread{
public void run(){
for (int i = 0; i < 60; i++) {
System.out.println("demo run--"+i);
}
}
}
public class ThreadDemo {
public static void main(String[] args) {
Demo d=new Demo(); //创建 一个线程
d.start(); //开始启动 线程,并执行该线程的 run()方法
//d.run(); 仅仅是 对象调用方法,还是交给主线程运行 ,而线程对象创建了,并没有运行.
for (int i = 0; i < 60; i++) {//主线程运行的代码
System.out.println("Hello world--"+i);
}
}
}
Thread
/**
* 练习:
* 创建两个线程,和主线程交替运行.
*
* 原来 线程都有自己的名称
* Thread-编号 ,编号从0 开始
* static Thread currentThread():获取当前线程对象
*
* getName():获取线程的名称.
* 设置线程名称:setName或者构造函数.
*
*/
class Test extends Thread{
//private String name; //原来线程 都有自己的名字 从 Thread_0
Test(String name){
//this.name=name;
super(name);
}
public void run(){
for (int i = 0; i < 60; i++) {
System.out.println((Thread.currentThread()==this)+this.getName()+" run ..."+i);
}
}
}
public class ThreadDemo2 {
public static void main(String[] args) {
Test t1=new Test("one--");
Test t2=new Test("two++");
t1.start();
t2.start();
for (int i = 0; i < 60; i++) {
System.out.println("main run ..."+i);
}
}
}
线程运行的状态

Thread 买票
/**
* 需求:简单的买票程序
* 4个窗口同时买票
*/
class SaleTicket extends Thread{
private static int ticks=100; //必须是静态的 发现 这个静态变量的声明周期太长.
public void run(){
while(true){
if(ticks>0){
System.out.println(Thread.currentThread().getName()+"---sale--"+ticks--);
}else
currentThread().stop();
}
}
}
public class ThreadDemo3 {
public static void main(String[] args) {
SaleTicket t1=new SaleTicket();
SaleTicket t2=new SaleTicket();
SaleTicket t3=new SaleTicket();
SaleTicket t4=new SaleTicket();
t1.start();
//t1.start(); 已经开启的线程 不需要在开启,也就是 说 一个线程 的start()不能被调用多次.
t2.start();
t3.start();
t4.start();
}
}
Runnable
/**
* 需求 :卖票的简单程序
*多个窗口同时卖票
*
*创建线程的第二种方式,实现 Runnable接口
*
*步骤:
*1.定义类实现Runnable接口
*2.覆盖Runnable接口中的run方法 (将线程要运行的代码放在run方法中)
*3.通过Thread类建立对象.
*4.将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数.
* 因为自定义的 run方法所属的对象是 Runnable接口的子类对象.
* 所以要让线程去执行指定对象run方法,就必须明确该run所属对象.
*5.调用Thread的start方法开启线程并调用Runnable接口子类中的run方法
*
*
*实现方式 和 继承 有什么区别呢?
*
*实现方式好处: 避免了单继承的局限性
*在定义线程时: 建议使用个 实现方式.
*
*两种方式的区别:
*继承Thread:线程代码存放Thread子类run方法中
*实现Runnable:线程代码存放在接口的子类的run方法中
*
*/
class SaleTicket implements Runnable{
private int ticks=100;
public void run(){
while(true){
if(ticks>0){
System.out.println(Thread.currentThread().getName()+"---sale--"+ticks--);
}
}
}
}
public class ThreadDemo1 {
public static void main(String[] args) {
SaleTicket t1=new SaleTicket();
Thread th1=new Thread(t1); //创建了一个线程 并将Runnable 子类对象给 Thread 构造函数
Thread th2=new Thread(t1);
Thread th3=new Thread(t1);
Thread th4=new Thread(t1);
th1.start();
th2.start();
th3.start();
th4.start();
}
}
