多线程实现的两种方式:
一、①继承Thread类,重写run()方法
②实现Runnable接口,重写run()方法
二、通过Thread类的构造器来创建线程对象
①Thread()
②Thread(Runnable target)
三、通过start方法激活线程对象
start();
run( )方法 — 线程运行体
要将一段代码(线程体)在一个新的线程上运行,该代码应该在一个线程类的run( )函数中
写一个类implements Runnable接口,且必须覆盖Runnable接口中的run( )方法
写一个类extends Thread类,且必须重写Thread类的run( )方法
两种实现方式的比较
①使用Runnable接口可以避免由于java单继承带来的局限
②适合多个相同程序代码的线程与处理同意资源情况,把线程同程序的代码、数据有效的分开
线程的状态及其生命周期
start( ) — 方法使线程处于可以运行的状态,但 不一定意味着该线程立即开始运行。
线程类中的主要方法
isActive();
getPriority();
setPriority();
Thread.sleep();
join(); 必须这个线程执行完,当前线程才能继续执行
yield(); 让出cpu,当前线程进入就绪队列等待调度
Object类中线程的相关方法
wait(); 当前的线程等待,直到其他线程调用此对象的 notify()方法或 notifyAll() 方法。
nitify();唤醒在此对象监视器上等待的单个线程。
notifyAll();唤醒在此对象监视器上等待的所有线程。
线程同步
什么是线程同步:
有时两个或多个线程可能会试图同时访问一个资源,为了确保在任何时间点一个共享的资源只被一个线程使用,使用了“同步”。当一个线程运行到需要同步的语句后,CPU不去执行其他线程中的、可能影响当前线程中的下一句代码的执行结果的代码块,必须等到下一句执行完后才能去执行其他线程中的相关代码块,这就是线程同步。
实现同步的两种方式
①锁定方法
synchronized void methodA(){ }
②锁定代码块
synchronized (Object){ }
package com.neusoft.action;
public class TestSync implements Runnable {
public static int num = 2;
// Timer2 timer = new Timer2();//锁定代码块
Timer timer = new Timer();
public static void main(String[] args) {
TestSync test = new TestSync();
Thread t1 = new Thread(test);
Thread t2 = new Thread(test);
Thread t3 = new Thread(test);
t1.setName("user1");
t2.setName("user2");
t3.setName("user3");
t1.start();
t2.start();
t3.start();
}
@Override
public void run() {
// TODO Auto-generated method stub
timer.Sc(Thread.currentThread().getName());
}
}
package com.neusoft.action;
public class Timer {
public synchronized void Sc(String name)
{
if(TestSync.num>0){
System.out.println("你好,当前系统余票数量为:"+TestSync.num);
TestSync.num--;
System.out.println(name+"订票成功!");
System.out.println();
}else{
System.out.println("当前系统余票数量为:"+TestSync.num);
System.out.println(name+"订票失败!");
}
try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
package com.neusoft.action;
public class Timer2 {
public void Sc(String name) {
//锁定代码块
synchronized (this) {
TestSync.num--;
try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(name + "你好,当前系统余票数量为:" + TestSync.num);
}
}
}
使得线程处于阻塞状态的几种方式:
①调用线程的sleep()方法,直到休眠指定的时间后醒来
②在线程上执行一个I/O阻塞动作
③线程A试图获得锁,而该锁呗其他线程持有
④线程在等待某个条件,如果条件不足则阻塞等待 (wait()方法)
⑤线程被调用suspend方法挂起