多线程Thread笔记(初)
一、 线程简介
世间万物都可以同时完成很多工作,例如,人体可以同时进行呼吸、血液循环、思考问题等活动,用户既可以使用计算机听歌,也可以使用它打印文件,而这些活动完全可以同时进行,这种思想放在Java中被称为并发,而将并发完成的每一件事情称为线程。
1. 定义线程的方法 :
<1>继承Thread接口,并重写run()方法
<2>实现Runnable接口。(详情请看DefinitionThread定义线程包)
线程的一些方法:
setName(String name)方法设置线程名称
getName()方法获取线程的名称
setPriority(int num)设置线程的优先级
getPriority()获取线程的优先级
setDaemon()设置一个线程为守护线程,该线程不会单独执行,当其他非守护线程都执行结束后,自动退出
join()方法加入线程,新加入的线程执行完毕后再执行本身线程,带int型参数表示等待指定毫秒之后继续运行本身线程,不管加入的线程是否执行完毕
Thread.currentThread()获取当前线程对象
Thread.sleep(毫秒)方法控制线程休眠若干毫秒
2. 线程的生命周期:
(七个状态)出生状态、就绪状态、运行状态、等待状态、休眠状态、阻塞状态、死亡状态
在start()方法之前线程都处于出生状态,当用户调用start()方法后,线程处于就绪状态,当线程得到系统资源后就进入运行状态(sleep()休眠方法、wait()等待方法、notify()通知/唤醒方法、interrupt()离开run()方法,结束线程)
3.操作线程的方法:
(1)、线程的休眠 --> 调用sleep()方法,
有一个参数为休眠的毫秒每个对象都有一个锁,sleep()方法不会释放锁
(2)、多线程情况下其他线程的加入 --> 调用join()方法,
当某个线程使用join()方法加入到另外一个线程时,另一个线程会等待该线程执行完毕再继续执行(例:A线程下B线程调用了join()方法,A线程会等待B线程完成后再执行)
(3)、线程的中断–>
<1>利用if判断在某种情况下使用break语句跳出循环
<2>调用Interrupt()方法,离开run方法,结束线程但程序会抛出InterruptException异常,用户可以在处理异常时完成线程的中断业务处理,如终止while循环
(4)、线程的礼让–>调用yield方法,
调用yield()方法后,程序会从运行状态进入就绪状态,而不是阻塞状态。
(也就是说会让cpu再次选举需要运行的线程,所以有可能再次选举还是执行本线程)
3. 线程的优先级:
系统会先运行优先级高的线程,高的运行完后再运行优先级低的线程。(注意:这是概率成面的先运行,也就是说优先级高的不一定就比优先级低的先运行,优先级高的只是先执行的概率比较高)
Thread的成员变量代表某些优先级:Thread.MIN_PRIORITY(常数1)、Thread.MAX_PRIORITY(常数10)、Thread.NORM_PRIORITY(常数5)
每个线程的优先级都在MIN和MAX之间,默认情况下是NORM。新线程继承父线程的优先级。
4.线程同步:
(1)、线程安全:
实际开发中,使用多线程程序的情况很多,如银行排号系统、火车站售票系统等。这种多线程的程序通常会发生问题,以火车站售票系统为例,在代码中判断当前票数是否大于0,如果大于0则执行将该票出售给乘客的功能,但当两个线程同时访问这段代码是(假如这是只剩下一张票),第一个线程将票售出,与此同时第二个线程也执行完成判断是否有票的操作,并得出票数大于0的结论,于是它也执行售出操作,这样就会产生负数。
int num = 10;
public void run() {
while(true) {
if(num>0) { //判断是否有空余票
try{
Thread.sleep(100);
}catch() {
e.printStackTrace();
}
System.out.println(“tickets” + num--); //出售票
}
}
}
(2)、线程的同步机制:
为了解决多线程资源冲突问题的方法都是采用给定时间只允许一个线程访问共享资源
1.同步块
在java中提供了同步机制,可以有效防止资源冲突。同步机制使用synchronized关键字。语法:synchronized(Object){ }
(通常将共享资源的操作放置在synchronized定义的区域内,这样当其他线程也获取到这个锁时,必须等锁被释放时才能进入该区域,Object为任意一个对象,每个对象都存在一个标志位,并具有两个值,分别为0和1)
int num = 10;
public void run() {
while(true) {
synchronized(“”) {
if(num>0) { //判断是否有空余票
try{
Thread.sleep(100);
}catch() {
e.printStackTrace();
}
System.out.println(“tickets” + num--); //出售票
}
}
}
}
2.同步方法
同步方法就是在方法面前修饰synchronized关键字的方法,其语法如下:
synchronized void f() { }
当某个对象调用了同步方法时,该对象上的其他同步方法等待该同步方法执行完毕后才能被执行。必须将每个能访问共享资源的方法修饰为synchronized,否则就会出错。
例:public synchronized void doit() { //定义同步方法
public synchronized void doit() { //定义同步方法
if(num > 0) {
try {
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("tickets" + --num);
}
}
public void run() {
while(true) {
doit(); //在run方法中调用该同步方法
}
}