您的位置:首页 > 编程语言 > Java开发

java的多线程机制上

2015-07-03 22:36 323 查看
------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------


一、多线程概述

package com.laobi.day12;

public class ThreadTest01 {
/**
* 进程:正在进行中的程序(直译)
*
* 线程:就是进程中一个程序执行的控制单元(执行路径)
*      一个进程中可以多执行路径,称之为多线程
*
* 一个进程中至少要有一个线程
*
* 开启多个线程是为了同时运行多部分代码
*
* 每一个线程都有自己运行的内容。这个内容可以称为线程要执行的任务
*
* 多线程的好处:解决了多部分同时运行的问题
* 多线程的弊端:线程太多会导致效率的降低
*
* 其实应用程序的执行都是cpu在做着快速的切换完成的。这个切换时随机的。
*
* jvn启动时就启动了多个线程,至少有两个线程可以分析出来的
* 1、执行main函数的线程
*    该线程的任务代码都定义在main函数中
* 2、负责垃圾回收的线程
*
*
* @param artcool
*/
public static void main(String[] args) {
Demo d1 = new Demo("旺财");  //主线程运行示例
Demo d2 = new Demo("小强");
d1.show();
d2.show();
//		new Demo();      jvm线程演示
//		System.gc();
System.out.println("diu");
}

}
class Demo
{
private String name;

public Demo(String name) {
super();
this.name = name;
}

public void show()
{
for(int x=0;x<10;x++)
{
for(int y=0;y<999999999;y++){}
System.out.println("demo 走"+name+"..."+x);
}
}
}


二、创建线程

package com.laobi.day12;

public class ThreadTest02 {
/**
* 如何创建一个线程呢?
* 创建线程方式一:继承Thread类
*
* 步骤:
* 1、定义一个类继承Thread类。
*
* 2、覆盖Thread类中的run方法。
*
* 3、直接创建Thread的子类对象
* 4、调用start方法开启线程并调用线程的任务run方法执行
*
* 可以通过Thread的getName获取线程的名称  Thread——编号
*
* 主线程的名字就是main
* @param args
*/
public static void main(String[] args) {
/*创建线程的目的是为了开启一条执行路径,去运行指定的代码和其他代码实现同时运行
而运行的指定代码就是这个执行路径的主任务
jvm创建的主线程的任务都定义在了主函数中
而自定义的线程它的任务在哪?
Thread类用于描述线程,线程是需要任务的。所以Thread类也对任务的描述
这个任务就是通过Thread类中的run方法来体现。也就是说,run方法就是封装自定义线程运行任务的函数

run方法中定义就是线程要运行的代码任务

开启线程是为了运行指定代码,所以只有继承Thread类,并复写run方法
*/
//		Thread t1 = new Thread();
Demo2 d1 = new Demo2("jack");
Demo2 d2 = new Demo2("tom");
d1.start();
d2.start();

}

}
class Demo2 extends Thread
{
private String name;
Demo2(String name)
{
this.name = name;
}
public void run()
{
show();
}
public void show()
{
for(int x=0;x<10;x++)
{
for(int y=0;y<999999;y++)
{
}
System.out.println(name+"...."+x+"..."+Thread.currentThread().getName());
}
}
}


三、Thread类的基本获取和设置方法

1)获取线程名字

Thread类中方法 String getName()

在一个不是Thread子类中获取名字:

Thread类中静态方法

static Thread currentThread()

返回正在运行的,当前线程对象 Thread类对象

继续使用线程对象的 getName()获取线程的名字

Thread类的方法 void setName(String name)设置线程名

Thread(String name) 用的是Thread类构造方法

子类使用super访问父类构造器

在Thread子类中,获取线程名字,直接使用父类方法getName()

在不是Thread子类中,通用代码,Thread.currentThread().getName()

四、线程的优先级的获取和设置

Thread类方法getPriority() 获取到优先级

Thread类方法setPriority(int t) 设置优先级

package com.test.xiancheng;

public class Test07 {
/**
*线程的生命周期及状态转换
*1、新建状态(new)
*   创建一个线程对象后,该线程对象就处于新建状态,此时它不能运行,和其他Java对象
*   一样,仅仅由Java虚拟机为其分配了内存,没有表现出任何线程的动态特征
*2、就绪状态(runnable)
*   当线程对象调用了Start()方法后,线程就进入就绪状态了。
*   此时它只是具备了运行条件,能否获得cpu的使用权开始运行,还需要等待系统的调度
*3、运行状态(running)
*   如果出就绪状态的线程获得了cpu的使用权,开始执行run()方法中的线程执行体,则该线程处于运行状态。
*4、阻塞状态(blocked)
*   一个正在执行的线程在某些特殊情况下,如执行耗时的输入/输出操作时,会放弃cpu使用权,进入阻塞状态。
*   阻塞就不能进入阻塞状态后,就不能进入排队队列。
*   例举一下线程由运行状态转换成阻塞状态的原因
*   a、当线程试图获取某个对象的同步锁时,如果该锁被其他线程所持有,则当前线程会进入阻塞状态,
*      如果想从阻塞状态进入就绪状态必须获得其他线程所持有的锁
*   b、当线程调用了一个阻塞式的io方法时,该线程就会进入阻塞状态,如果想进入就绪状态就必须要等到这个阻塞的
*      io方法返回
*   c、当线程调用了某个对象的wait()时,也会使线程进入阻塞状态,如果想进入就绪状态就需要使用
*      notify()方法唤醒该线程
*   d、当线程调用了Thread的sleep(long mills)方法时,也会使线程进入阻塞状态,在这种情况下
*      只需等到线程的睡眠时间到了以后,线程就会自动进入就绪状态
*   f、当在一个线程中调用另一个线程的join()方法时,会使当前线程进入阻塞状态,在这种情况下,需要等到
*      需要等到新加入的线程运行结束后才会结束阻塞状态,进入就绪状态
*   线程从阻塞状态只能进入就绪状态
*5、死亡状态(Terminated)
*    线程的run()方法正常执行完毕或者线程抛出一个未捕获的异常(Exception)、错误(Error),线程
*    就会进入死亡状态。一旦进入死亡状态I,线程将不再拥有运行的资格,也不能再转换到其他状态
*
*
*线程的调度:分别是分时调度模型和抢占式调度模型
*分时调度:让所用的线程轮流获得cpu的使用权,并且平均分配cpu的时间片
*抢占式调度:让可运行池中优先级高的线程优先占用cpu,而对优先级相同的
*          线程,随机选择一个线程占用cpu,当它失去cpu的使用权后,
*          再随机选择其他线程获取cpu使用权。
*1、线程的优先级:
*   如果需要对线程进行调度,最直接的方式就是设置线程的优先级
*2、线程休眠:
*   使正在执行的线程暂停,将cpu让给别的线程,这是可以使用sleep(),该方法可以让当前正在执行
*   的线程暂停一段时间,进入休眠等待状态。
*3、线程让步:
*   可以通过yield()方法来实现,该方法和sleep有点相似,都可以让正在运行的线程暂停,
*   区别在于yield()方法不会阻塞线程,他只是将线程转换成就绪状态,让系统调度器重新调度一次
*4、线程插队:
*   当在某个线程中调用其他线程的join()方法时,调用的线程将被阻塞,直到
*   被join()方法加入的线程执行完成后他才会继续运行
*
*
* 多线程同步:
* 1、线程安全
* 2、线程同步方法
* 3、同步方法:当把共享资源的操作放在synchronized定义的区域内时,便为这些操作加了同步锁
*              在方法前面同样可以使用synchronized关键字来修饰,被修饰的方法为同步方法,它能实现
*              和同步代码块同样的功能。被synchronized修饰的方法在某一时刻只允许一个线程访问
*              ,访问该方法的其他线程都会被阻塞,直到当前线程访问完毕后,其他线程才有机会执行方法
*
*/
public static void main(String[] args) {
Thread minPriorty = new Thread(new MinProirty(),"优先级较低的线程");
Thread maxPriorty = new Thread(new MaxPriorty(),"优先级较高的线程");
minPriorty.setPriority(Thread.MIN_PRIORITY);
maxPriorty.setPriority(10);
maxPriorty.start();
minPriorty.start();
}

}
class MaxPriorty implements Runnable
{
public void run()
{
for(int i=0;i<=10;i++)
{
System.out.println(Thread.currentThread().getName()+"正在输出:"+i);
}
}
}
class MinProirty implements Runnable
{
public void run()
{
for(int i=0;i<=10;i++)
{
System.out.println(Thread.currentThread().getName()+"正在输出:"+i);
}
}
}


五、线程休眠

package com.test.xiancheng;

public class XCxiumian {
/**
* 线程休眠:
*   使正在执行的线程暂停,将cpu让给别的线程,这是可以使用sleep(),该方法可以让当前正在执行
*   的线程暂停一段时间,进入休眠等待状态。
* @throws Exception
*/
public static void main(String[] args) throws Exception {
new Thread(new SleepThread()).start();
for(int i=1;i<=10;i++)
{
if(i==5)
{
Thread.sleep(2000);
}
System.out.println("主线程正在输出:"+i);
Thread.sleep(500);
}
}

}
class SleepThread implements Runnable
{
public void run()
{
for(int i=1;i<=10;i++)
{
if(i==3)
{
try
{
Thread.sleep(2000);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
System.out.println("线程一正在输出:"+i);
try
{
Thread.sleep(500);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
}


五、线程让步

package com.test.xiancheng;

public class XCrangbu {
/**
* 线程让步:
*   可以通过yield()方法来实现,该方法和sleep有点相似,都可以让正在运行的线程暂停,
*   区别在于yield()方法不会阻塞线程,他只是将线程转换成就绪状态,让系统调度器重新调度一次
*
*/
public static void main(String[] args) {
Thread t1 = new YieldThread("线程A");
Thread t2 = new YieldThread("线程B");
t1.start();
t2.start();
}

}
class YieldThread extends Thread
{
public YieldThread(String name)
{
super(name);
}
public void run()
{
for(int i=0;i<5;i++)
{
System.out.println(Thread.currentThread().getName()+"----"+i);
if(i==3)
{
System.out.print("线程让步:");
Thread.yield();//线程运行到此,做出让步
}
}
}
}


六、线程插队

package com.test.xiancheng;

public class XCchadui {
public static void main(String[] args) throws Exception {
Thread t = new Thread(new EmergencyThread(),"线程一");
t.start();
for(int i=1;i<6;i++)
{
System.out.println(Thread.currentThread().getName()+"输入:"+i);
if(i==2)
{
t.join();
}
Thread.sleep(500);
}
}

}
class EmergencyThread implements Runnable
{
public void run()
{
for(int i=1;i<6;i++)
{
System.out.println(Thread.currentThread().getName()+"输入:"+i);
try
{
Thread.sleep(500);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: