java之11天 多线程 (一)

本文详细阐述了进程与线程的概念,包括主线程与自定义线程的区别,以及如何通过继承Thread类或实现Runnable接口来创建线程。同时,介绍了线程的运行状态,并通过实例演示了线程的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[size=medium][b]进程 线程
main 和 run 的区别 [/b][/size]

/**
*进程:是一个正在执行的程序
* 每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元.
* (一个进程中个至少有一个线程)
*
*线程: 就是进程中的一个独立的控制单元.
* 线程在控制这进程的执行
*
*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);
}
}

}



[size=medium][b]Thread[/b][/size]

/**
* 练习:
* 创建两个线程,和主线程交替运行.
*
* 原来 线程都有自己的名称
* 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);
}
}
}



[size=medium][b]线程运行的状态[/b][/size]

[img]http://dl.iteye.com/upload/attachment/0082/9006/fc27d0da-d32f-38f9-8b80-6e098f1348ae.png[/img]

[size=medium][b]Thread 买票[/b][/size]

/**
* 需求:简单的买票程序
* 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();
}

}


[size=medium][b]Runnable[/b][/size]

/**
* 需求 :卖票的简单程序
*多个窗口同时卖票
*
*创建线程的第二种方式,实现 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();

}

}


[img]http://dl.iteye.com/upload/attachment/0082/9008/ede8ca67-fa5c-3768-b783-cefb1a7bdd16.png[/img]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值