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.初步了解"进程"."线程"."多线程" 说到多线程,大多都会联系到"进程"和"线程".那么这两者 ...
随机推荐
- Liferay7 BPM门户开发之42: Liferay核心JSP定制扩展
Liferay最大的好处是不仅接口强大,利于扩展,就连JSP定制扩展都提供了3种方式. 修改核心jsp代码,有3种修改方式:1.暴力修改直接修改(位于portal-web/docroot/html), ...
- chrome开发总结(交互/权限/存储)-爬虫
chrome开发总结(交互/权限/存储)-爬虫 [TOC] 标签(空格分隔): 杂乱之地 经过一翻折腾.还是选择了chrome来做爬虫.主要是为了解决一些ajax加载的问题以及代理的问题. 1.chr ...
- Unity3D协同程序(Coroutine)
摘要下: 1. coroutine, 中文翻译"协程".这个概念可能有点冷门,不过百度之,说是一种很古老的编程模型了,以前的操作系统里进程调度里用到过,现在操作系统的进程调度都是根 ...
- Activity间中使用Intent传值
主页面用来输入一个值传入第二个页面显示,关闭第二个页面返回一个值 主页布局: <RelativeLayout xmlns:android="http://schemas.android ...
- go环境import cycle not allowed问题处理
1.前言 今天在搭建Go语言环境,从https://golang.org/dl/上下载一个Go语言环境.环境变量配置刚开始如下配置: GOROOT=/home/go/bin go执行文件目录 ...
- java类的初始化和对象的创建顺序
学习java编程思想--类的初始化p146 类的加载顺序* 1加载器启动找到 xxx.class文件,通过extends关键字寻找基类,先加载基类* 2类初始化先初始化static成员变量和stati ...
- [Java 基础]字符串
String类 实例化String对象 String 对象初始化方式有多种. 如下代码中,各种初始化方式的效果是一样的,初始化后,String 对象的内容为 "hello" . p ...
- web框架--bottle
安装 2 3 4 pip install bottle easy_install bottle apt-get install python-bottle wget http://bottlepy.o ...
- 基于HTML5技术的电力3D监控应用(二)
上篇介绍了我们电力项目的基本情况,我们选用HTML5技术还是顶着很大压力,毕竟HTML5技术性能行不行,浏览器兼容性会不会有问题,这些在项目选型阶段还是充满疑惑,项目做到现在终于快收尾了我们才敢松口气 ...
- 一个ajax同步与异步引发的血案。
前言 公司做网上促销活动,需要充值换取相应的抽奖资格,抽奖可以获得丰厚的礼品,而且抽奖资格门槛有点高,领导下达命令保证活动的正常上线与运行,领导很重视,就这样,在领导的安排下进行了相关活动的codin ...