创建线程

  • 创建线程的方式:
    • 继承java.lang.Thread
    • 实现java.lang.Runnable接口
  • 所有的线程对象都是Thead及其子类的实例
  • 每个线程完成一定的任务,其实就是一段顺序执行的代码

继承java.lang.Thread创建线程

public class Test1  {
public static void main(String[] args){
System.out.println("现在是主线程: "+Thread.currentThread());
//用静态方法获取当前正在执行的线程
System.out.println("下面新建两个线程");
new Test(100).start();
new Test(100).start();
//这里开启两个线程,但不是完成同一件任务
}
}
class Test extends Thread{
//继承Thread类
private int tickets;
Test (int tick){
tickets=tick;
}
public void run(){
for (;tickets>0;tickets--) {
System.out.println("当前线程:"+getName()+" 卖出第 "+tickets+" 张票。");
//用this获得当前线程
if (tickets==1){
System.out.println("票已卖完,当前线程是: "+getName());
}
}
}
}

0036 Java学习笔记-多线程-创建线程的三种方式

 

创建线程

  • 创建线程的三种方式:

    • 继承java.lang.Thread
    • 实现java.lang.Runnable接口
    • 实现java.util.concurrent.Callable接口
  • 所有的线程对象都是Thead及其子类的实例
  • 每个线程完成一定的任务,其实就是一段顺序执行的代码

继承java.lang.Thread创建线程

package testpack;

public class Test1  {
public static void main(String[] args){
System.out.println("现在是主线程: "+Thread.currentThread()); //用静态方法获取当前正在执行的线程
System.out.println("下面新建两个线程");
new A(100).start();
new A(100).start(); //这里开启两个线程,但不是完成同一件任务
}
}
class A extends Thread{ //继承Thread类
private int tickets;
A (int tick){
tickets=tick;
}
public void run(){
for (;tickets>0;tickets--) {
System.out.println("当前线程:"+getName()+" 卖出第 "+tickets+" 张票。"); //用this获得当前线程
if (tickets==1){
System.out.println("票已卖完,当前线程是: "+getName());
}
}
}
}
  • 继承Thread类,开启线程的步骤:

    • 定义一个类,继承Thread,重写run()方法,run()方法就是线程要完成的任务
    • 创建该类的实例,并调用start()方法启动线程
  • 继承Thread类开启的线程,各自完成各自的任务

实现java.lang.Runnable接口创建线程

public class Test1  {
public static void main(String[] args){
System.out.println("现在是主线程: "+Thread.currentThread());
System.out.println("下面新建两个线程");
Test test=new Test(100);
//创建一个任务的对象
new Thread(test,"线程A").start();
//以同一个任务对象为target,开启两个线程
new Thread(test,"线程B").start();
//两个线程完成同一项任务,但是二者协作沟通不好
}
}
class Test implements Runnable{
//实现Runnable接口
private int tickets;
Test (int tick){
tickets=tick;
}
public void run(){
//同样重写run()方法,就是线程要完成的任务
for (;tickets>0;tickets--) {
System.out.println("当前线程:"+Thread.currentThread()+" 卖出第 "+tickets+" 张票。");
if (tickets==1){
System.out.println("票已卖完,当前线程是: "+Thread.currentThread());
}
}
}
}
  • 实现Runnable接口开启线程的步骤:

    • 定义一个类,实现Runnbale接口,重写run()方法
    • 创建该类的对象,即任务对象
    • 以任务对象为target,创建线程,调用start()方法
  • 通过Runnable接口创建的多个线程,可以写作完成同一件任务,只是协作方面有待改进

Thread、Runnable的比较

  • Thread:

    • 不能继承其他类;
    • 用this获取当前线程
    • 多个线程不能执行同一个target任务
  • Runnable:
    • 可以继承其他类;
    • 用Thread.currentThread()获取当前线程
    • 多个线程可以执行同一个target任务

线程的生命周期

  • 新建(New):

    • 创建线程对象后,就处于“新建”状态,此时跟一个普通的对象无异
    • 只能对新建状态的线程对象,调用start()方法
  • 就绪(Runnable):
    • 调用start()方法后,处于就绪状态,虚拟机为其创建方法调用栈和程序计数器
    • 何时开始运行,取决于JVM的调度
    • 就绪状态可能从“新建”、“阻塞”、“运行”三种状态变化而来
  • 运行(Running):
    • 线程获得了在CPU上运行的权利,开始运行
    • 何时中断执行,也取决于调度,一个线程不可能一直占着cpu
    • 一个线程,可以调用sleep()或者yield()方法,来主动放弃执行权利
  • 阻塞(Blocked):
    • 调用sleep()方法
    • 调用了一个阻塞式的IO方法,该方法返回之前,被阻塞
    • 试图获得一个同步监视器,但该监视器被其他线程所持有
    • 等待其他线程的notify()通知
    • 调用suspend()方法将该线程挂起。尽量避免该种方法,可能导致死锁
  • 死亡(dead):
    • 线程任务执行完成
    • 线程抛出未捕获的异常或错误
    • 调用线程的stop()方法
    • 主线程运行结束,不影响子线程的继续运行
    • boolean isAlive()方法返回线程是否已死亡:处于新建和死亡两种状态返回false,其他三种状态返回true

start()与run()方法

    • 永远不要调用线程对象的run()方法。直接调用run()方法的话,那么就只是一个普通方法,而不是线程任务
    • 调用了run()方法之后,会改变线程对象的状态,不再是新建状态,因而也就不能调用start()方法
    • 只能对处于新建状态的线程对象调用start()方法,且只能调用一次,否则抛出IllegalThreadStateException异常

Java学习笔记-多线程-创建线程的方式的更多相关文章

  1. 0036 Java学习笔记-多线程-创建线程的三种方式

    创建线程 创建线程的三种方式: 继承java.lang.Thread 实现java.lang.Runnable接口 实现java.util.concurrent.Callable接口 所有的线程对象都 ...

  2. 0038 Java学习笔记-多线程-传统线程间通信、Condition、阻塞队列、《疯狂Java讲义 第三版》进程间通信示例代码存在的一个问题

    调用同步锁的wait().notify().notifyAll()进行线程通信 看这个经典的存取款问题,要求两个线程存款,两个线程取款,账户里有余额的时候只能取款,没余额的时候只能存款,存取款金额相同 ...

  3. java学习笔记 --- 多线程(线程安全问题——同步代码块)

    1.导致出现安全问题的原因: A:是否是多线程环境 B:是否有共享数据 C:是否有多条语句操作共享数据 2.解决线程安全问题方法: 同步代码块: synchronized(对象){ 需要同步的代码; ...

  4. 0037 Java学习笔记-多线程-同步代码块、同步方法、同步锁

    什么是同步 在上一篇0036 Java学习笔记-多线程-创建线程的三种方式示例代码中,实现Runnable创建多条线程,输出中的结果中会有错误,比如一张票卖了两次,有的票没卖的情况,因为线程对象被多条 ...

  5. java学习笔记 --- 多线程(多线程的创建方式)

    1.创建多线程方式1——继承Thread类. 步骤:  A:自定义类MyThread继承Thread类.  B:MyThread类里面重写run()? 为什么是run()方法呢? C:创建对象 D:启 ...

  6. 0041 Java学习笔记-多线程-线程池、ForkJoinPool、ThreadLocal

    什么是线程池 创建线程,因为涉及到跟操作系统交互,比较耗费资源.如果要创建大量的线程,而每个线程的生存期又很短,这时候就应该使用线程池了,就像数据库的连接池一样,预先开启一定数量的线程,有任务了就将任 ...

  7. JAVA学习笔记16——控制线程

    Java的线程支持提供了一些便捷的工具方法,通过这些便捷的工具方法可以很好地控制线程执行.   join线程 Thread提供了让一个线程等待另一个线程完成的方法——join().当在某个线程执行流中 ...

  8. 0039 Java学习笔记-多线程-线程控制、线程组

    join线程 假如A线程要B线程去完成一项任务,在B线程完成返回之前,不进行下一步执行,那么就可以调用B线程的join()方法 join()方法的重载: join():等待不限时间 join(long ...

  9. 0040 Java学习笔记-多线程-线程run()方法中的异常

    run()与异常 不管是Threade还是Runnable的run()方法都没有定义抛出异常,也就是说一条线程内部发生的checked异常,必须也只能在内部用try-catch处理掉,不能往外抛,因为 ...

随机推荐

  1. sharepoint2013的审核日志的时间区域设置

    最近在项目中碰到审核日志的时间为GMT格式 ,如何格式化成本地时间. 网站集设置成本地区域无法解决此类问题,后来查询资料才知道.无法更改 Change Audit Time From GMT Time ...

  2. How to get Timer Job History

    1. Get Timer Job internal name with id. Job ID can be found in SharePoint CA. Below PowerShell can h ...

  3. android studio 导入项目太慢(卡条)

    原因: 下载的项目和你当前已经下载的grandle 不一致, 导致导入的时候到网上下载相应的版本. 最简单的办法,修改你这个需要导入的项目. 需要修改的文件: 1. xxx-project/.idea ...

  4. 基于Ruby的watir-webdriver自动化测试方案与实施(一)

    基于Ruby的watir-webdriver自动化测试方案与实施(五)   基于Ruby的watir-webdriver自动化测试方案与实施(四)   基于Ruby的watir-webdriver自动 ...

  5. 将String转化成Stream,将Stream转换成String

    using System;using System.IO;using System.Text;namespace CSharpConvertString2Stream{     class Progr ...

  6. Oracle监听服务启动失败案例

    在ORACLE测试服务器上还原恢复了一个数据库后,启动监听服务时出现了TNS-12541, TNS-12560,TNS-00511之类的错误,具体情况如下所示: [oracle@getlnx01 ad ...

  7. javascript-代理模式

    JavaScript代理模式笔记 由于一个对象不能直接引用另一个对象,所以要用过代理对象在这两个对象之间起到中介作用 1.代理对象形式是通过script标签 demo实例实现的方式也被人称之为JSON ...

  8. Spring配置JNDI和通过JNDI获取DataSource

    一.SpringJNDI数据源配置信息 <bean id="dataSource" class="org.springframework.jndi.JndiObje ...

  9. .net core 用grpc实现微服务

    GRPC 是Google发布的一个开源.高性能.通用RPC(Remote Procedure Call)框架.提供跨语言.跨平台支持.以下以.NET Core 使用控制台.docker中演示如何使用G ...

  10. Fiddler进行模拟Post提交数据,总为null解决方式

    Fiddler模拟post提交时总是为空,解决办法 如果是表单提交则要在header加上 ContentType:application/x-www-form-urlencoded 如果是要post提 ...