java进阶06 线程初探

  线程,程序和进程是经常容易混淆的概念。

  程序:就是有序严谨的指令集

  进程:是一个程序及其数据在处理机上顺序执行时所发生的活动

  线程:程序中不同的执行路径,就是程序中多种处理或者方法。

  线程有两种方法实现

  一:继承Thread 覆盖run方法

  


package Thread;

public class Thread1 {
public static void main(String[] args){
MyThread1 thread1=new MyThread1();
thread1.setName("线程1");
thread1.start();

MyThread1 thread2=new MyThread1();
thread2.setName("线程2");
thread2.start();

for(int i=0;i<5;i++)
System.out.println("主线程正在执行");
}

}
class MyThread1 extends Thread{
public void run(){
for(int i=0;i<20;i++)
{
System.out.println(Thread.currentThread().getName()+"正在执行"+i);
}
}
}

  由于线程是由CPU随机分配的,所以输出结果中 会发现 各线程的执行顺序也是随机的。

  部分输出结果:

  主线程正在执行
  主线程正在执行
  线程2正在执行0
  线程2正在执行1
  线程2正在执行2
  线程2正在执行3
  线程2正在执行4
  线程1正在执行0
  线程2正在执行5
  线程1正在执行1
  线程2正在执行6

  

  2:实现接口Runnable 实现run方法

  


package Thread;

public class Runnable1 {
//实际开发推荐使用该方法
public static void main(String[] args){
MyThread2 rthread=new MyThread2();
//由于接口中的方法都是抽象的 所以无法直接调用start()
Thread thread1=new Thread(rthread);
Thread thread2=new Thread(rthread);

thread1.setName("线程1");
thread2.setName("线程2");

thread1.start();
thread2.start();

for(int i=0;i<20;i++)
System.out.println("主线程正在执行");
}

}
//通过实现接口Runnable实现
class MyThread2 implements Runnable{
public void run(){
for(int i=0;i<20;i++)
{
System.out.println(Thread.currentThread().getName()+"正在执行"+i);
}
}
}

  部分输出结果:

  主线程正在执行
  主线程正在执行
  线程1正在执行0
  线程2正在执行0
  线程1正在执行1
  线程2正在执行1

  线程的使用就这么简单,不过在实际开发中一般使用第二种方法好点.

  从程序可以看出,由于是随机分配CPU所以无法实现线程的执行的顺序,那有办法吗?

  有,就是设置优先级

  


package Thread;

public class ThreadPrority {
public static void main(String[] args){
MyThread3 rthread=new MyThread3();

Thread thread1=new Thread(rthread);
Thread thread2=new Thread(rthread);

thread1.setName("线程1");
thread2.setName("线程2");

thread1.setPriority(1);//设置优先级 默认是5
thread2.setPriority(9);

thread1.start();
thread2.start();
}
}
//通过实现接口Runnable实现
class MyThread3 implements Runnable{
public void run(){
for(int i=0;i<30;i++)
{
System.out.println(Thread.currentThread().getName()+"正在执行"+i);
}
/*设置了优先级 不代表优先级高的就一定会执行 只有更有几率从CPU那分取到。
* */
}
}

  输出结果:

  线程1正在执行0
  线程2正在执行0
  线程1正在执行1
  线程2正在执行1
  线程1正在执行2
  线程2正在执行2
  线程1正在执行3
  线程2正在执行3
  线程1正在执行4
  线程2正在执行4
  线程1正在执行5
  线程2正在执行5
  线程1正在执行6
  线程2正在执行6

  这里你一定会有疑问 这不是没变么,主要是这里循环的次数太低 而计算机运算的速度太快,想要看效果 可以把循环次数调高些。

  这些就是线程的基本操作。线程还可以睡眠,在睡眠的时间段CPU不会让调用它的对象参与竞争。

  


package Thread;

public class ThreadSleep {
public static void main(String[] args){
MyThread4 rthread=new MyThread4();
Thread thread=new Thread(rthread);
thread.setName("线程");
thread.start();
}
}
//通过实现接口Runnable实现
class MyThread4 implements Runnable{
public void run(){
for(int i=0;i<100;i++)
{
System.out.println(Thread.currentThread().getName()+"正在执行"+i);
try {
Thread.sleep(1000);//线程睡眠1s
} catch (Exception e) {
// TODO: handle exception
System.out.println("线程出错");
}
/*只得注意的是 这里要处理线程睡眠的异常,而且不能向上一级throws
*因为throws,是其调用类的父类或者其实现的接口中有该方法,才能向上throws
*这里实现的Runnable里面的抽象方法中并没有throws方法
*所以这里如果throws的话 会出错 只能用try...catch来处理
*/
}
}
}

  输出结果:

  线程正在执行0
  线程正在执行1
  线程正在执行2
  线程正在执行3
  线程正在执行4

  它会隔1秒输出一句。Tread.Sleep(1000);这里的1000是毫秒 同时这里要处理异常,值得注意的是。这里的异常只能用try...catch。

  而且不能向上一级throws
     
因为throws,是其调用类的父类或者其实现的接口中有该方法,才能向上throws
     
这里实现的Runnable里面的抽象方法中并没有throws方法
      所以这里如果throws的话 会出错
只能用try...catch来处理

  就像 线程不能直接调用run方法,而要调用start一样,因为接口中的方法是抽象的。

  在Thread里面可以调用run方法,但是它并不会另开线程,而是把run直接调用,相当于在主线程运行一个函数而已。

java进阶06 线程初探,码迷,mamicode.com

时间: 2024-10-08 11:13:27

java进阶06 线程初探的相关文章

java进阶07 线程的让步与阻塞与同步

前面介绍了线程的一些基本知识,现在来说下线程的让步,阻塞,和同步 先说说让步 所谓让步,就是让调用者的线程暂停,让其他线程重新竞争CPU,包括调用者. 先看看代码 package Thread; public class ThreadYield { public static void main(String[] args){ MyThread5 rthread=new MyThread5(); Thread thread1=new Thread(rthread); Thread thread2

Java进阶(三)多线程开发关键技术

原创文章,转载请务必将下面这段话置于文章开头处. 本文转发自Jason's Blog,原文链接 http://www.jasongj.com/java/multi_thread/ sleep和wait到底什么区别 其实这个问题应该这么问--sleep和wait有什么相同点.因为这两个方法除了都能让当前线程暂停执行完,几乎没有其它相同点. wait方法是Object类的方法,这意味着所有的Java类都可以调用该方法.sleep方法是Thread类的静态方法. wait是在当前线程持有wait对象锁

Java 进阶(一) JVM运行时内存模型

1.JVM运行时数据区域的划分 a.程序计数器(Program Counter Register) 一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器.每个线程拥有独立的一个计数器,如果当前执行的是Native方法,则计数器值为空. b.JVM栈(Java Virtual Machine Stack) 描述Java方法执行的内存模型,每个方法在执行的同时都会创建一个栈帧(Stacks Frame)用于存储局部变量表,操作数栈,动态链接,方法出口等信息. 每一个方法从调用直至执行完成

Java进阶之路

Java进阶之路--从初级程序员到架构师,从小工到专家. 怎样学习才能从一名Java初级程序员成长为一名合格的架构师,或者说一名合格的架构师应该有怎样的技术知识体系,这是不仅一个刚刚踏入职场的初级程序员也是工作三五年之后开始迷茫的老程序员经常会问到的问题.希望这篇文章会是你看到过的最全面最权威的回答. 一: 编程基础 不管是C还是C++,不管是Java还是PHP,想成为一名合格的程序员,基本的数据结构和算法基础还是要有的.下面几篇文章从思想到实现,为你梳理出常用的数据结构和经典算法. 1-1 常

Java进阶教程:Streams API

Java进阶教程:Streams API Stream是啥 首先明确一点,Stream流和IO包里的InputStream.OutputStream是完全不同的概念!它是Java 8 中引入的新特性,Stream可以对集合元素进行各种高效.便利的聚合操作! 聚合是个什么东东呢? 聚合在信息科学中是指对有关的数据进行内容挑选.分析.归类,最后分析得到人们想要的结果,主要是指任何能够从数组产生标量值的数据转换过程 [1]  .近年来随着大数据的发展,聚合技术已经广泛地应用于文本分析,信息安全,网络传

Java进阶教程:HashMap实现原理

Java进阶教程:HashMap实现原理 有一段时间没写博客了,现在连组织语言的能力都下降了... 关于HashMap 你必须要知道的 HashMap是我们开发中最常用的数据结构,功能强大,但是说句实话,却又是最陌生的,如果没有打开JDK拜读过他的代码,研究他的实现,甚是可惜.今天我们一起来研究一下HashMap. 当然如果只是面试需要的话,记住这三点也可以蒙混过关: HashMap线程不安全,HashTable(上古产物)是线程安全的,如果要保证线程安全可以用ConcurrentHashMap

【JAVA进阶架构师指南】之四:垃圾回收GC

前言 ??在[JAVA进阶架构师指南]系列二和三中,我们了解了JVM的内存模型以及类加载机制,其中在内存模型中,我们说到,从线程角度来说,JVM分为线程私有的区域(虚拟机栈/本地方法栈/程序计数器)和线程公有区域(方法区和java堆),其中线程私有区域内存随着线程的结束而跟着被回收,GC主要关注的是堆和方法区这部分的内存. GC回收算法 ??GC如何确定哪些对象需要回收呢?一般而言,有两种算法:引用计数算法和可达性分析算法. 引用计数算法 ??为每个对象都持有一个引用计数器,初试状态为0,该对象

Java四种线程池newCachedThreadPool,newFixedThreadPool,newScheduledThreadPool,newSingleThreadExecutor

介绍new Thread的弊端及Java四种线程池的使用,对Android同样适用.本文是基础篇,后面会分享下线程池一些高级功能. 1.new Thread的弊端 执行一个异步任务你还只是如下new Thread吗? Java new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub } }).start(); 1 2 3 4 5 6 7 new Thread(new

Java进阶书籍推荐

学习Java,书籍是必不可少的学习工具之一,尤其是对于自学者而言.废话不多说,下边就给广大程序猿们推荐一些Java进阶的好书. 第一部分:Java语言篇 1.<Java编程规范> 适合对象:初级.中级 介绍:这本书的作者是被誉为Java之父的James Gosling,入门者推荐阅读,对基础的讲解很不错. 2.<Java编程思想> 适合对象:初级.中级 介绍:豆瓣给出了9.1的评分,全球程序员广泛赞誉.有人说这本书不适合初学者,不过小编认为作者并没有对读者已有的知识经验有过多要求,