Java 多线程
来源:互联网 发布:淘宝个人主页标签 编辑:程序博客网 时间:2024/06/11 02:34
Java 多线程
进程:是一个正在执行中的程序。
线程:执行路径或控制单元,是进程中的一个独立的控制单元,线程在控制着进程的进行。
一个进程中至少一个线程。
java 虚拟机启动的时候会有一个进程,java.exe.该进程中至少有一个线程负责java 程序的执行,而且这个线程运行的代码运行在于main方法中,该线程成为主线程。
扩展:更细节说明jvm,jvm启动不止一个线程,至少还有个垃圾回收的线程。
意义:可以让我们在程序中多步代码同时运行。
进程或线程的创建真正意义上是有所依赖的系统创建的。
创建执行线程有两种方法:
一.将类声明为Thread类的子类,该子类应当重写Thread类的run方法.
步骤:
1. 定义类继承Thread
2. 复写Thread类中的run方法,目的是将自定义的代码存储在run方法中,让线程运行。
3. 调用线程的start方法,该方法有两个作用,第一,启动线程;第二调用run方法。
public class ThreadDemo { public static void main(String[] args) { Demo d = new Demo(); //创建好一个线程 d.start(); for (int i = 0; i < 100; i++) { System.out.println("------"); } }}class Demo extends Thread { public void run() { for (int i = 0; i < 100; i++) { System.out.println("*****"); } }}
在ThreadDemo程序中:
我们会发现**和—-的打印并没有明确的先后顺序,每一次运行的结果都不同,因为多个线程都获取cpu的执行权,cpu执行到谁,谁就运行。明确一点,在某一个时刻,只能有一个程序运行。(多核除外),cpu在做着快速的切换,以达到看上去是同时运行的效果。此时有两条执行路径同时执行。其实并没有同时运行,只是系统对cpu进行快速的对这两个线程的调度。我们可以形象的把多线程的运行行为看做互相抢夺cpu的执行权。
这就是多线程的一个特点:随机性,谁抢到谁执行,至于执行多长,cpu说了算。
1.为什么要覆盖run方法?
Thread 类用于描述线程,该类定义了一个功能,用于存储线程要运行的代码,该存储功能就是run方法。也就是说Thread类中的run方法,用于存储线程要运行的代码。
2.run方法和start方法的区别?
public static void main(String[] args) { Demo d = new Demo(); //创建好一个线程 //d.start(); //开启线程并执行该线程的run方法。 d.run();//仅仅是对象调用方法,而线程创建了,但并没有运行。 for (int i = 0; i < 100; i++) { System.out.println("------"); } }
练习:创建两个线程,和主线程交替运行.
public class ThreadDemo { public static void main(String[] args) { Text t1 = new Text("one"); Text t2 = new Text("two"); t1.start(); t2.start(); for (int i = 0; i < 1000; i++) { System.out.println("------"); } }}class Text extends Thread { private String name; public Text(String name){ this.name=name; } public void run() { for (int i = 0; i < 1000; i++) { System.out.println(name+"*****"); } }}
线程的五种状态:
自定义线程名称
每个线程都有它自己默认的名称。
Thread-编号,该编号从0开始。
getName();和setName();我们可以用线程的构造器构造线程的时候起名称。
public class ThreadDemo { public static void main(String[] args) { Text t1 = new Text("one"); Text t2 = new Text("two"); t1.start(); t2.start(); for (int i = 0; i < 1000; i++) { System.out.println("------"); } }}class Text extends Thread { public Text(String name) { super(name); //直接调用父类的构造方法 } public void run() { for (int i = 0; i < 1000; i++) { System.out.println((Thread.currentThread()==this)+this.getName() + "*****"); } }}
static Thread currentThread(); 获取当前的线程对象
getName():获取线程的名称
需求:简单的买票程序
多个窗口同时卖票。
/** * Created by Pitcher on 2017/9/25 0025 * Email:943990494@qq.com */public class TicketDemo { public static void main(String[] args) { Ticket t1=new Ticket(); Ticket t2=new Ticket(); Ticket t3=new Ticket(); Ticket t4=new Ticket(); t1.start(); t2.start(); t4.start(); }}class Ticket extends Thread{ private static int tick=100; public void run(){ while (true){ if(tick>0){ System.out.println(currentThread().getName()+"....sale"+tick--); } } }}
虽然这样可以实现,但是把票数定义为静态变量,生命周期太长了,因此我们看第二种创建线程的方式。
第二种方法
声明实现Runnable 接口的类,该类然后实现run方法。然后就可以分配该类的实例。
步骤:
- 定义类实现Runnable
- 覆盖Runnable接口中的方法,将线程要运行的代码放入run方法中
- 通过Thread类建立线程对象
- 将Runnable接口中的子类对象作为实际参数传递给Thread类的构造函数,
- 调用Thread的start方法开启线程,并调用Runnable子类的run方法
/** * Created by Pitcher on 2017/9/25 0025 * Email:943990494@qq.com */public class TicketDemo { public static void main(String[] args) { Ticket t=new Ticket(); Thread t1=new Thread(t);//创建了一个线程 Thread t2=new Thread(t);//创建了一个线程 Thread t3=new Thread(t);//创建了一个线程 Thread t4=new Thread(t);//创建了一个线程 t1.start(); t2.start(); t3.start(); t4.start(); }}class Ticket implements Runnable{ private int tick=100; public void run(){ while (true){ if(tick>0){ System.out.println(Thread.currentThread().getName()+"....sale"+tick--); } } }}
为什么要实现Runnable 接口,因为Thread认识Runnable接口,我们在创建Thread的时候,将我们实现Runnable的对象传入其构造器中,就可以让该线程执行我们对象中的方法。
实现方式继承方式的区别?
实现方式的好处在于避免了单继承的局限性。在定义线程时,建议使用实现方式。
继承Thread:线程代码存放在Thread中,
实现Runnable:线程代码存放在子类的run方法中。
- 【Java多线程】多线程死锁
- Java 多线程
- java 多线程
- java多线程
- JAVA多线程
- java多线程
- JAVA多线程
- java多线程
- JAVA 多线程
- Java多线程
- java多线程
- JAVA 多线程
- Java 多线程
- Java 多线程
- java多线程
- Java 多线程
- Java多线程
- java 多线程
- Spring Cloud 监控服务器下 IP/URL 不正确导致无法注册的解决方法
- popwindow 动画取消奔溃报错java.lang.NullPointerException ViewRootImpl.drawAccessibilityFocusedDrawable
- 事件捕获e || window.event
- ESP8266 PWM&GPIO
- Redis lesson14 Redis 中的消息订阅
- Java 多线程
- 考研数学
- oracle 常用语法(转载)
- java读取资源文件的五种方式 (转载)
- 微信分享突然失效的解决方法记录
- 清除浮动的方法以及各自的优缺点
- 5. pstack 跟踪进程栈
- 学习SpringMVC——上传文件
- table排序