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.初步了解"进程"."线程"."多线程" 说到多线程,大多都会联系到"进程"和"线程".那么这两者 ...
随机推荐
- IOS开发之控件篇UITabBarControllor第二章 - 遮掩TableView问题
在IOS7.0以后UITabBar 里面放入一个UITableView会出现一个问题,Table会被TabBar掩盖了,当移动到最后一项的时候,永远看不到,如下面的例子,总共是99项,但是只能显示到9 ...
- TypeScript实例
interface Person { firstName: string, lastName: string } function greeter(person: Person) { return p ...
- java基础-继承:矩形体积类问题
28.按要求编写一个Java应用程序: (1)定义一个类,描述一个矩形,包含有长.宽两种属性,和计算面积方法. (2)编写一个类,继承自矩形类,同时该类描述长方体,具有长.宽.高属性, 和计算体积的方 ...
- 代码生成AnimatorController
0.出发点 现在的项目需要设置多套动画组合,全部是由策划在XML文件中设置完成,如果完全的手动在AnimatorController中去做不但工作量大而且如果将来有配置修改了还要一个个去找到对应的自状 ...
- javase基础复习攻略《二》
今天就开始的真正走进JAVASE的世界,本篇介绍的是:JAVASE基础语法,大家如果有C语言的基础,对于本节内容一定感觉非常轻松,编程语言之间的都是相通的,只不过C语言属于面向过程编程,而JAVA语言 ...
- SQL*Loader之CASE5
CASE5 1. SQL脚本 [oracle@node3 ulcase]$ cat ulcase5.sql set termout off rem host write sys$output &quo ...
- 深入浅出JSONP--解决ajax跨域问题
取不到数据! 上周客户新买了服务器,原本在旧的服务器上放着客户的Web主页信息和一个后台程序(asp.net),在客户的主页中有一个动态显示最新消息的处理,这个处理就是通过ajax异步从那个后台程序中 ...
- Python编码问题整理
认识常见编码 GB2312是中国规定的汉字编码,也可以说是简体中文的字符集编码 GBK 是 GB2312的扩展 ,除了兼容GB2312外,它还能显示繁体中文,还有日文的假名 cp936:中文本地系统是 ...
- Hadoop阅读笔记(三)——深入MapReduce排序和单表连接
继上篇了解了使用MapReduce计算平均数以及去重后,我们再来一探MapReduce在排序以及单表关联上的处理方法.在MapReduce系列的第一篇就有说过,MapReduce不仅是一种分布式的计算 ...
- 简单的jquery拖曵原理js特效实例
<!DOCTYPE html> <html> <title>简单拖曵原理实例</title> <script language="jav ...