java多线程功力
例如:网上购物时邮件通知程序,用户单击提交按钮确认订单时,一方面要显示信息提示用户订单已经确认,一方面应该自动给用户发送一份电子邮件。
二、实例化线程
要重写继承的run()方法,run()方法中的代码就是线程所要执行任务的描述。
一旦线程启动,run方法中的代码将成为一条独立的执行线索。
注意,重写后的run方法虽然具有成为执行线索的能力,但也可以作为一般的方法调用,直接调用run方法并不产生新的执行线索
若想得到一个线程,必须创建Thread类或其子类对象,这时就要使用Thread类的特定构造器来完成这个工作。
//创建实现Runnable接口的类的对象。
MyRunnable mr=new MyRunnable();
Thread t=new Thread(mr);
这种方式实际上是告诉线程对象要执行的任务run方法在哪里。
实现Runnable接口的类的对象只是指出了线程需要完成的任务,其本身并不是线程对象。
* 实现Runnable接口的类
*
* @author leizhimin 2008-9-13 18:12:10
*/
public class DoSomething implements Runnable {
private String name;
public DoSomething(String name) {
this.name = name;
}
public void run() {
for (int i = 0; i < 5; i++) {
for (long k = 0; k < 100000000; k++) ;
System.out.println(name + ": " + i);
}
}
}
* 测试Runnable类实现的多线程程序
*
*/
public class TestRunnable {
public static void main(String[] args) {
DoSomething ds1 = new DoSomething("阿三");
DoSomething ds2 = new DoSomething("李四");
Thread t1 = new Thread(ds1);
Thread t2 = new Thread(ds2);
t1.start();
t2.start();
}
}
阿三: 0
李四: 1
阿三: 1
李四: 2
李四: 3
阿三: 2
李四: 4
阿三: 3
阿三: 4
Process finished with exit code 0
* 测试扩展Thread类实现的多线程程序
*
*/
public class TestThread extends Thread{
public TestThread(String name) {
super(name);
}
public void run() {
for(int i = 0;i<5;i++){
for(long k= 0; k <100000000;k++);
System.out.println(this.getName()+" :"+i);
}
}
public static void main(String[] args) {
Thread t1 = new TestThread("阿三");
Thread t2 = new TestThread("李四");
t1.start();
t2.start();
}
}
李四 :0
阿三 :1
李四 :1
阿三 :2
李四 :2
阿三 :3
阿三 :4
李四 :3
李四 :4


一旦处于准备状态的线程获取了CPU时间,就进入运行状态,在运行状态下,线程随时可能被调度程序调度到准备状态,线程在执行时,由于需要等待某些必要条件可能会进入等待阻塞状态。
同时又几个线程能处于运行状态取决于硬件,如果是双核(每核心一线程)CPU,同一时刻可能有两个线程处于运行状态。
java自动调度没有逻辑约束的线程时,其执行顺序是没有保障的,但是可以通过编程调用一些调度线程的方法,来实现一定程度上对线程的调度。
有些调度方法是有保障的,有些只是影响线程进入运行状态的概率。
静态方法强制当前正在执行的线程休眠(暂停执行),以“减慢线程”。当线程睡眠时,它入睡在某个地方,在苏醒之前不会返回到可运行状态。当睡眠时间到期,则返回到准备状态。
这两个方法不是与某个线程对象相关联的,其可以出现在任何位置,当执行到该方法时,让执行此方法的线程进入睡眠状态。
注意线程醒来将进入准备状态,并不能保证立即执行,因此指定的时间是线程暂停执行的最小时间。
Thread.sleep(123);
} catch (InterruptedException e) {
e.printStackTrace();
}
//定义实现Runnable接口的类
class MyRunnable1 implements Runnable
{
//重写run方法,指定该线程执行的代码
public void run()
{
for(int i=0;i<5;i++)
{
System.out.println("["+i+"] 我是线程1!!!");
//使此线程进入睡眠状态
try
{
Thread.sleep(100);
}
catch(InterruptedException ie)
{
ie.printStackTrace();
}
}
}
}
//定义另外一个实现Runnable接口的类
class MyRunnable2 implements Runnable
{
//重写run方法,指定该线程执行的代码
public void run()
{
for(int i=0;i<5;i++)
{
System.out.println("<"+i+"> 我是线程2!!!");
//使此线程进入睡眠状态
try
{
Thread.sleep(100);
}
catch(InterruptedException ie)
{
ie.printStackTrace();
}
}
}
}
public class Sample16_3
{
public static void main(String[] args)
{
//创建实现Runnable接口的类
MyRunnable1 mr1=new MyRunnable1();
MyRunnable2 mr2=new MyRunnable2();
//创建线程Thread对象,并指定各自的target
Thread t1=new Thread(mr1);
Thread t2=new Thread(mr2);
//启动线程t1
t1.start();
//使主线程进入睡眠状态
try
{
Thread.sleep(5);
}
catch(InterruptedException ie)
{
ie.printStackTrace();
}
//启动线程t2
t2.start();
}
}
在没有特别指定的情况下,主线程的优先级为5,对于子线程,其初始优先级与其父线程的优先级相同。
JVM线程调度程序是基于优先级的抢先调度机制。在大多数情况下,当前运行的线程优先级将大于或等于线程池中任何线程的优先级。但这仅仅是大多数情况。
t.setPriority(8);
t.start();
java中的线程优先级是依赖于本地平台的,在实际运行时会将线程在java中的优先级映射到本地的某个优先级。这样,如果本地提供的优先级比10个要少,则java中的不同的优先级可能会映射成相同的本地优先级,而具有基本相同的执行概率。
class MyThread1 extends Thread
{
public void run()
{
for(int i=0;i<=49;i++)
{
System.out.print("<xiao"+i+"> ");
}
}
}
class MyThread2 extends Thread
{
public void run()
{
for(int i=0;i<=49;i++)
{
System.out.print("[大"+i+"] ");
}
}
}
public class aa
{
public static void main(String[] args)
{
MyThread1 t1=new MyThread1();
MyThread2 t2=new MyThread2();
t1.setPriority(Thread.MIN_PRIORITY);
t2.setPriority(Thread.MAX_PRIORITY);
t1.start();
t2.start();
}
}
这里并不是说高优先级的一直占用CPU,只是说高优先级的争夺的机会大,交替执行还是存在的。
二:线程将给指定的线程让步,指定线程没有完成,其绝不恢复执行。
yield()方法
结论:yield()从未导致线程转到等待/睡眠/阻塞状态。在大多数情况下,yield()将导致线程从运行状态转到准备状态,但有可能没有效果。
class MyRunnable implements Runnable
{
private String flagl;
private String flagr;
public MyRunnable(String flagl,String flagr)
{
this.flagl=flagl;
this.flagr=flagr;
}
public void run()
{
for(int i=0;i<30;i++)
{
System.out.print(flagl+i+flagr);
//调用yield方法使当前正在执行的线程让步
Thread.yield();
}
}
}
public class Sample16_5
{
public static void main(String[] args)
{
//创建两个实现Runnable接口的类的对象
MyRunnable mr1=new MyRunnable("[","] ");
MyRunnable mr2=new MyRunnable("<","> ");
//创建两个线程Thread对象,并指定执行的target
Thread t1=new Thread(mr1);
Thread t2=new Thread(mr2);
//启动线程t1、t2
t1.start();
t2.start();
}
}
这里线程时交替执行的,但是是没有保障的,有时交替有时无法做到。
join()方法
当一个线程必须等待另一个线程执行完毕时,才恢复执行时使用join方法。是有保障的。
class MyThread extends Thread
{
public void run()
{
for(int i=0;i<30;i++)
{
System.out.print("["+i+"] ");
}
System.out.print("{子线程执行结束} ");
}
}
public class Sample16_6
{
public static void main(String[] args)
{
Thread t=new MyThread();
t.start();
for(int i=0;i<30;i++)
{
if(i==10)
{
//主线程中调用join方法使主线程进行让步
try
{
System.out.print("{使用了Jion方法} ");
t.join();//等待该线程终止。
}
catch(InterruptedException ie)
{
ie.printStackTrace();
}
}
System.out.print("<"+i+"> ");
}
}
}

java多线程功力的更多相关文章
- 40个Java多线程问题总结
前言 Java多线程分类中写了21篇多线程的文章,21篇文章的内容很多,个人认为,学习,内容越多.越杂的知识,越需要进行深刻的总结,这样才能记忆深刻,将知识变成自己的.这篇文章主要是对多线程的问题进行 ...
- Java多线程基础知识篇
这篇是Java多线程基本用法的一个总结. 本篇文章会从一下几个方面来说明Java多线程的基本用法: 如何使用多线程 如何得到多线程的一些信息 如何停止线程 如何暂停线程 线程的一些其他用法 所有的代码 ...
- Java多线程系列--“JUC锁”03之 公平锁(一)
概要 本章对“公平锁”的获取锁机制进行介绍(本文的公平锁指的是互斥锁的公平锁),内容包括:基本概念ReentrantLock数据结构参考代码获取公平锁(基于JDK1.7.0_40)一. tryAcqu ...
- Java多线程系列--“JUC锁”04之 公平锁(二)
概要 前面一章,我们学习了“公平锁”获取锁的详细流程:这里,我们再来看看“公平锁”释放锁的过程.内容包括:参考代码释放公平锁(基于JDK1.7.0_40) “公平锁”的获取过程请参考“Java多线程系 ...
- Java多线程--让主线程等待子线程执行完毕
使用Java多线程编程时经常遇到主线程需要等待子线程执行完成以后才能继续执行,那么接下来介绍一种简单的方式使主线程等待. java.util.concurrent.CountDownLatch 使用c ...
- Java多线程 2 线程的生命周期和状态控制
一.线程的生命周期 线程状态转换图: 1.新建状态 用new关键字和Thread类或其子类建立一个线程对象后,该线程对象就处于新生状态.处于新生状态的线程有自己的内存空间,通过调用start方法进入就 ...
- java 多线程 1 线程 进程
Java多线程(一).多线程的基本概念和使用 2012-09-10 16:06 5108人阅读 评论(0) 收藏 举报 分类: javaSE综合知识点(14) 版权声明:本文为博主原创文章,未经博 ...
- 一起阅读《Java多线程编程核心技术》
目录 第一章 Java多线程技能 (待续...)
- 第一章 Java多线程技能
1.初步了解"进程"."线程"."多线程" 说到多线程,大多都会联系到"进程"和"线程".那么这两者 ...
随机推荐
- 建站集成软件包 XAMPP搭建后台系统与微信小程序开发
下载安装XAMPP软件,运行Apache和MySQL 查看项目文件放在哪个位置可以正常运行 然后访问localhost即可 下载weiphp官网的weiapp(专为微信小程序开发使用)放在htdocs ...
- KnockoutJS 3.X API 第四章(13) template绑定
目的 template绑定(模板绑定)使用渲染模板的结果填充关联的DOM元素. 模板是一种简单方便的方式来构建复杂的UI结构 . 下面介绍两种使用模板绑定的方法: 本地模板是支持foreach,if, ...
- PHP将富文本编辑后的内容,去除样式图片等只保留txt文本内容
1.从数据库读取富文本内容样式如下: <p style=";text-indent: 0;padding: 0;line-height: 26px"><span ...
- 队列-java代码
public class QueueDemo { private int maxSize; private long[] queueArray; // 队列的头,实际是数组的尾 private int ...
- java中得到classpath和当前类的绝对路径的一些方法(路径中的%20"进行替换空格)
原网址:http://blog.csdn.net/shendl/article/details/1427475 (注意:利用下面方式得到路径,如果路径中有空格字符, 那么会有"%20&quo ...
- 【原创】C#玩高频数字彩快3的一点体会
购彩风险非常高,本人纯属很久以前对数字高频彩的一点研究.目前已经远离数字彩,重点研究足球篮球比赛资料库和赛果预测. 这是一篇在草稿箱保存了1年多的文章,一直没发现,顺便修改修改分享给大家.以后会有更多 ...
- Linux - Screen
GNU's Screen homepage Screen是由GNU计划开发的用于命令行终端切换的自由软件,可以看作是窗口管理器的命令行界面版本. 可以通过该软件同时连接多个本地或远程的命令行会话,并在 ...
- AngularJS in Action读书笔记3——走近Services
试着想想这些问题:如果一个controller只关心自己所控制的view页面,那么对于整个application来说,你如何调用想要的function:如果controller从来都不会和其他cont ...
- Windows Azure Web Site (6) 使用FTP发布Azure Web Site
<Windows Azure Platform 系列文章目录> 笔者在之前的文章中介绍的都是使用IDE,也就是Visual Studio,将本地的aspx发布到Azure Web Site ...
- 在Elasticsearch中查询Term Vectors词条向量信息
这篇文章有点深度,可能需要一些Lucene或者全文检索的背景.由于我也很久没有看过Lucene了,有些地方理解的不对还请多多指正. 更多内容还请参考整理的ELK教程 关于Term Vectors 额, ...