「java线程新手」java 线程使用
本篇文章给大家谈谈java线程新手,以及java 线程使用对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。
本文目录一览:
- 1、JAVA线程新手问题,为什么这样子线程不会退出?
- 2、JAVA 线程数组新手排序问题
- 3、Java多线程编程基础之线程和多线程
- 4、Java多线程初学者指南(12):使用Synchronized块同步变量
- 5、Java多线程初学者指南(3):使用Runnable接口创建线程
JAVA线程新手问题,为什么这样子线程不会退出?
程序启动两个线程,一个是main ,一个是你开的线程ADaemon,而ADaemon是以
个守护线程,也就是说是在后台运行的。
当你的线程 sleep (2000) 的时候,main 先于ADaemon结束,所以System.out.println("this shoould always run?");看不见,
假如不sleep (2000) ,这个main和ADaemon,就会竞争,假如 ADaemon先于 main之前结束,
你肯定就可以看见System.out.println("this shoould always run?");
JAVA 线程数组新手排序问题
import java.util.*;
public class print {
public static void main(String[] args) {
int[] s = { 1, 5, 2, 42, 53, 23, 12, 43 };
IntPrint p1 = new IntPrint(1, s);// 进行从小到大输出的线程
IntPrint p2 = new IntPrint(-1, s);// 进行从大到小输出的线程
p1.start();
p2.start();
}
}
class IntPrint extends Thread {
private int a;
private int[] str;
public IntPrint(int a, int[] str) {
this.a = a;
this.str = str;
}
public void run() {
Arrays.sort(str); // 对数组进行升序排序
if (a = 0) { // a=0进行从小到大输出
for (int i = 0; i str.length; i++) {
System.out.print(str[i] + " ");
}
} else if (a 0) {// a0进行从大到下输出
for (int i = (str.length - 1); i = 0; i--) {
// 为了区分上边这每打印一个换行,除了最后一行需要判断以外其他的每行的
//最后一个均为该线程输出的
System.out.println(str[i] + " ");
}
}
}
}
Java多线程编程基础之线程和多线程
随着计算机技术的发展 编程模型也越来越复杂多样化 但多线程编程模型是目前计算机系统架构的最终模型 随着CPU主频的不断攀升 X 架构的硬件已经成为瓶 在这种架构的CPU主频最高为 G 事实上目前 G主频的CPU已经接近了顶峰
如果不能从根本上更新当前CPU的架构(在很长一段时间内还不太可能) 那么继续提高CPU性能的方法就是超线程CPU模式 那么 作业系统 应用程序要发挥CPU的最大性能 就是要改变到以多线程编程模型为主的并行处理系统和并发式应用程序
所以 掌握多线程编程模型 不仅是目前提高应用性能的手段 更是下一代编程模型的核心思想 多线程编程的目的 就是 最大限度地利用CPU资源 当某一线程的处理不需要占用CPU而只和I/O OEMBIOS等资源打交道时 让需要占用CPU资源的其它线程有机会获得CPU资源 从根本上说 这就是多线程编程的最终目的
第一需要弄清的问题
如同程序和进程的区别 要掌握多线程编程 第一要弄清的问题是 线程对象和线程的区别
线程对象是可以产生线程的对象 比如在java平台中Thread对象 Runnable对象 线程 是指正在执行的一个指点令序列 在java平台上是指从一个线程对象的start()开始 运行run方法体中的那一段相对独立的过程
鉴于作者的水平 无法用更确切的词汇来描述它们的定义 但这两个有本质区别的概念请初学者细细体会 随着介绍的深入和例程分析的增加 就会慢慢明白它们所代表的真实含义
天下难事必始于易 天下大事必始于细
让我们先从最简单的 单线程 来入手 ( )带引号说明只是相对而言的单线程 ( )基于java
class BeginClass{ public static void main(String[] args){ for(int i= ;i ;i++) System out println( Hello World! ); } }
如果我们成功编译了该java文件 然后在命令行上敲入
java BeginClass
现在发生了什么呢?每一个java程序员 从他开始学习java的第一分钟里都会接触到这个问题 但是 你知道它到底发生发什么?
JVM进程被启动 在同一个JVM进程中 有且只有一个进程 就是它自己 然后在这个JVM环境中 所有程序的运行都是以线程来运行 JVM最先会产生一个主线程 由它来运行指定程序的入口点 在这个程序中 就是主线程从main方法开始运行 当main方法结束后 主线程运行完成 JVM进程也随之退出
我们看到的是一个主线程在运行main方法 这样的只有一个线程执行程序逻辑的流程我们称
之为单线程 这是JVM提供给我们的单线程环境 事实上 JVM底层还至少有垃圾回收这样的后台线程以及其它非java线程 但这些线程对我们而言不可访问 我们只认为它是单线程的
主线程是JVM自己启动的 在这里它不是从线程对象产生的 在这个线程中 它运行了main方法这个指令序列 理解它 但它没有更多可以研究的内容
接触多线程
class MyThread extends Thread{ public void run(){ System out println( Thread say:Hello World! ); } } public class MoreThreads{ public static void main(String[] args){ new MyThread(); new MyThread() start(); System out println( Main say:Hello World ); } }
执行这个程序 main方法第一行产生了一个线程对象 但并没有线程启动
main方法第二行产生了一个线程对象 并启动了一个线程
main方法第三行 产生并启动一个线程后 主线程自己也继续执行其它语句
lishixinzhi/Article/program/Java/gj/201311/27552
Java多线程初学者指南(12):使用Synchronized块同步变量
我们可以通过synchronized块来同步特定的静态或非静态方法 要想实现这种需求必须为这些特性的方法定义一个类变量 然后将这些方法的代码用synchronized块括起来 并将这个类变量作为参数传入synchronized块 下面的代码演示了如何同步特定的类方法
package mythread; public class SyncThread extends Thread { private static String sync = ; private String methodType = ; private static void method(String s) { synchronized (sync) { sync = s; System out println(s); while (true); } } public void method () { method( method ); } public static void staticMethod () { method( staticMethod ); } public void run() { if (methodType equals( static )) staticMethod (); else if (methodType equals( nonstatic )) method (); } public SyncThread(String methodType) { thodType = methodType; } public static void main(String[] args) throws Exception { SyncThread sample = new SyncThread( nonstatic ); SyncThread sample = new SyncThread( static ); sample start(); sample start(); } }
运行结果如下
method staticMethod
看到上面的运行结果很多读者可能感到惊奇 在上面的代码中method 和staticMethod 方法使用了静态字符串变量sync进行同步 这两个方法只能有一个同时执行 而这两个方法都会执行 行的无限循环语句 因此 输出结果只能是method 和staticMethod 其中之一 但这个程序将这两个字符串都输出了
出现这种结果的愿意很简单 我们看一下 行就知道了 原来在这一行将sync的值改变了 在这里要说一下Java中的String类型 String类型和Java中其他的复杂类型不同 在使用String型变量时 只要给这个变量赋一次值 Java就会创建个新的String类型的实例 如下面的代码所示
String s = hello ;System out println(s hashCode());s = world ;System out println(s hashCode());
在上面的代码中 第一个s和再次赋值后的s的hashCode的值是不一样的 由于创建String类的实例并不需要使用new 因此 在同步String类型的变量时要注意不要给这个变量赋值 否则会使变量无法同步
由于在 行已经为sync创建了一个新的实例 假设method 先执行 当method 方法执行了 行的代码后 sync的值就已经不是最初那个值了 而method 方法锁定的仍然是sync变量最初的那个值 而在这时 staticMethod 正好执行到synchronized(sync) 在staticMethod 方法中要锁定的这个sync和method 方法锁定的sync已经不是一个了 因此 这两个方法的同步性已经被破坏了
解决以上问题的方法当然是将 行去掉 在本例中加上这行 只是为了说明使用类变量来同步方法时如果在synchronized块中将同步变量的值改变 就会破坏方法之间的同步 为了彻底避免这种情况发生 在定义同步变量时可以使用final关键字 如将上面的程序中的 行可改成如下形式
private final static String sync = ;
使用final关键字后 sync只能在定义时为其赋值 并且以后不能再修改 如果在程序的其他地方给sync赋了值 程序就无法编译通过 在Eclipse等开发工具中 会直接在错误的地方给出提示
我们可以从两个角度来理解synchronized块 如果从类方法的角度来理解 可以通过类变量来同步相应的方法 如果从类变量的角度来理解 可以使用synchronized块来保证某个类变量同时只能被一个方法访问 不管从哪个角度来理解 它们的实质都是一样的 就是利用类变量来获得同步锁 通过同步锁的互斥性来实现同步
lishixinzhi/Article/program/Java/gj/201311/27400
Java多线程初学者指南(3):使用Runnable接口创建线程
上一篇 Java多线程初学者指南( ) 用Thread类创建线程
实现Runnable接口的类必须使用Thread类的实例才能创建线程 通过Runnable接口创建线程分为两步
将实现Runnable接口的类实例化
建立一个Thread对象 并将第一步实例化后的对象作为参数传入Thread类的构造方法
最后通过Thread类的start方法建立线程
下面的代码演示了如何使用Runnable接口来创建线程
package mythread;public class MyRunnable implements Runnable{ public void run() { System out println(Thread currentThread() getName()); } public static void main(String[] args) { MyRunnable t = new MyRunnable(); MyRunnable t = new MyRunnable(); Thread thread = new Thread(t MyThread ); Thread thread = new Thread(t ); thread setName( MyThread ); thread start(); thread start(); }}
上面代码的运行结果如下
lishixinzhi/Article/program/Java/gj/201311/27466
关于java线程新手和java 线程使用的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。