黑马程序员 — 线程

------------android培训java培训、期待与您交流! ----------



线程


什么是线程:

专业定义:

利用对象,可将一个程序分割成相互独立的区域。我们通常也需要将一个程序转换成多个独立运行的子任

务。

象这样的每个子任务都叫作一个“线程”(Thread)。编写程序时,可将每个线程都想象成独立运行,而且

都有自己的专用 CPU。一些基础机制实际会为我们自动分割 CPU 的时间。我们通常不必关心这些细节问题,

所以多线程的代码编写是相当简便的。

这时理解一些定义对以后的学习狠有帮助。“进程”是指一种“自包容”的运行程序,有自己的地址空间。

“多任务”操作系统能同时运行多个进程(程序)——但实际是由于 CPU 分时机制的作用,使每个进程都能

循环获得自己的 CPU 时间片。但由于轮换速度非常快,使得所有程序好象是在“同时”运行一样。“线程”

是进程内部单一的一个顺序控制流。因此,一个进程可能容纳了多个同时执行的线程。

通俗定义:

线程是一个程序里的不同执行路径


为什么需要线程:

进程太浪费资源,进程切换需要花时间



线程的使用和请注意事项:

单线程:


程序有一个入口一个出口和一个顺序执行的序列,程序执行过程的任何时刻都只有一个单独的执行点


多线程:

在单个程序内部在同一时刻可以进行多种运算


多线程的优势:
多线程编程简单,高效(能直接共享数据和资源,多进程不能)
适合开发服务程序(web服务,聊天服务等)


创建线程的方法:


为创建一个线程,最简单的方法就是从 Thread 类继承。这个类包含了创建和运行线程所需的一切东西。
Thread 最重要的方法是 run()。但为了使用 run(),必须对其进行过载或者覆盖,使其能充分按自己的吩咐
行事。因此,run()属于那些会与程序中的其他线程“并发”或“同时”执行的代码。


第一种:


创建一个继承Thread的类A,

并重写从Thread继承来的run方法,

构造一个A类对象aa,

调用aa对象的start方法(start方法从Thread继承来,会创建一个新线程,并自动调用aa对象的run方法).

注意:直接调用run方法不会创建线程

执行一个线程就是执行该线程的run方法

执行完aa.start()表示aa线程具有了可以立即被cpu执行的资格,

但由于抢占cpu执行的线程很多,cpu不一定立即执行aa线程

一个Thread对象只能代表一个线程,不能调用两次start方法


第二种:


定义一个实现Runnable接口的类A,

创建A类对象aa,

利用aa构造一个Thread对象tt ,(Thread中的一个构造方法public Thread(Runnable r))

Thread tt = new Thread(aa);

调用tt中的start方法.

注意:Runnable接口中只有一个void run()方法

Thread类中的常用方法
public final void setName(Sting name)设置当前线程的名字

public static Thread currentThread()返回对当前正在执行的线程的对象的引用 public final String getName()返回当前线程的名字


线程的控制:


线程的三个状态:就绪状态,运行状态,阻塞状态
线程控制的基本方法
isAlive()判断线程是否还未终止(三个状态都是活着)
getPriority()获得线程的优先级
setPriority()设置线程的优先级
Thread.sleep()让当前线程睡眠指定毫秒(由运行到阻塞)
join()调用某线程的该方法,将当前线程与该线程合并,即等待该线程结束,再恢复当前线程的运行
yield()让出cpu,当前线程进入就绪队列等待调度(由运行到就绪)
wait()当前线程进入对象wait pool

notify()/notifyAll() 唤醒对象的wait pool中的一个/所有等待进程



线程的优先级:

线程的优先级从1到10,主线程的缺省优先级是5,子线程的优先级默认和其父线程相同 java提供一个线程调度器监控程序启动后进入就绪状态的所有线程,按线程优先级决定执行顺序

Thread.MIN_PRIORITY = 1
Thread.NORMAL_PRIORITY = 5
Thread.MAX_PRIORTIY = 10
获得和设置线程对象的优先级

int getPriority();

void setPriority(int newPriority)

通常优先级高的线程先于优先级低的线程执行,但不总是这样,实际开发中并不单纯依赖优先级来决定线程运行次序







线程的休眠:


  • 暂停执行当前运行的线程,使之进入阻塞状态,经过指定的延迟时间后再醒来并进入到就绪状态
  • Thread类提供的方法
  • public static void sleep(long millis)
  • public static void sleep(long millis, int 
  • 会抛出InterruptedException异常,必须用try catch捕获子类继承Thread类或实现Runnable接口的run方法都不能抛出异常


为何会堵塞

  • 堵塞状态是前述四种状态中最有趣的,值得我们作进一步的探讨。线程被堵塞可能是由下述五方面的原因造
  • 成的:
  • 调用 sleep(毫秒数),使线程进入“睡眠”状态。在规定的时间内,这个线程是不会运行的。
  • 用 suspend()暂停了线程的执行。除非线程收到 resume() 消息,否则不会返回“可运行”状态。
  • 用 wait()暂停了线程的执行。除非线程收到 nofify() 或者 notifyAll()消息,否则不会变成“可运行”
  • 线程正在等候一些 IO(输入输出)操作完成。
  • 线程试图调用另一个对象的“同步”方法,但那个对象处于锁定状态,暂时无法使用。


死锁:

有两个线程,彼此都需要对方的资源才可以运行,但双方都不愿意先让出自己的资源让对方运行,导致双方都在等待,一直得不到运行。



线程的让步:


让出cpu,给其他线程执行的机会

运行中的线程主动放弃当前获得cpu处理的机会,进入就绪状态

public static void yield()


线程的串行化:


在多线程程序中,如果一个线程运行的过程用到了另一个线程的运行结果,则可以进行线程的串行化处理
public final void join() throws InterruptedException

t.join()暂停执行t.join()的这个线程,等待t线程运行完毕,这个线程才会获得继续执行的机会


线程的同步:

synchronized关键字
synchronized可以修饰一个方法或方法内的某个代码块
synchronized修饰代码块
格式:
synchronized(随便一个类对象名aa)
{

同步代码块

}


说明:
判断aa是否被其他线程霸占,如果发现已霸占,当前线程等待,如果没有被霸占当前线程霸占aa对象,执行同步代码块,执行完自动释放对aa的霸占,线程再次竞争对aa的霸占,cpu会选择一个线程霸占aa

结果:一个线程操作某资源时,不允许其他线程操作该资源,即一次只允许一个线程处理该资源



synchronized修饰方法:

synchronized修饰方法时,实际霸占的是该方法的this指针所指向的对象,即正在调用该方法的对象
霸占的专业术语叫锁定,霸占住对象专业术语叫监听器
疑:买票程序用expends thread方法能不能把类里要锁定的字符串设置为数据区的字符串|String str = "aaa";不加static


卖票程序:


class A implements Runnable
{
	public int ticket = 100;
	String str = new String("哈哈");
	public void run()
	{
		String str = "哈哈";
		
		while(true)
		{
			synchronized(str)  // //  synchronized 保证了当前线程没执行完13行到23行的代码时,其它线程不能访问该代码
			{
				if(ticket > 0)
				{
					System.out.printf("%s线程正在卖出第%d张票\n",Thread.currentThread().getName(),ticket);
					--ticket;
				}
				else
				{
					break;
				}
			}
		}
	}
}

public class TestTickets_8
{
	public static void main(String[] args)
	{
		A aa = new A();
		Thread t1 = new Thread(aa);
		t1.start();
		Thread t2 = new Thread(aa);
		t2.start();
	}
}










  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值