(1)做一个非常耗时间的代码,线程执行循环读写操作
(2)使用线程让多个代码同时执行,视频下载
(1)前台线程(执行线程)
自己执行,自己停止
(2)后台线程(守护线程/精灵线程)
该线程不会单独执行, 当其他非守护线程都执行结束后, 自动退出【守护线程 也可以守护 main线程】
(1)继承Thread类
写一个普通类继承Thread类,重写run()方法
使用:通过new一个Thread的实例,调用start方法让这个线程进入就绪状态
Thread t = new MyThread();
t.start();
(2)实现Runnable接口
写一个普通类实现Runnable类,实现run()方法
使用:
Ruunable r = new MyRunnable();
Thread t = new Thread(r);
t.start();
(1)实例方法
(2)启动线程,线程只能启动一次
(1)是一个静态方法,可通过类名直接调用
(2)获取当前正在运行的线程
(1)实例方法
(2)给调用该方法的线程获取或者设置名字
(1)是一个静态本地方法,这个方法的特点就是可以通过实例/类名来调用
(2)调用sleep()方法的线程,会让出CPU进入阻塞状态,结束睡眠之后,进入就绪状态,sleep()睡眠时保持对象锁。
(1)是一个静态本地方法,这个方法的特点就是可以通过实例/类名来调用
(2)调用yield()方法的线程会让出CPU给那些优先级比我的当前线程高或者同级的线程去使用(建议性的),调用这个方法的线程会进入就绪状态,再次去争取CPU的使用权,调用yield()方法并不会释放对象锁,
(1)实例方法
(2)有线程t1和t2,在线程t1中调用t2.join()方法表示:t1线程进入阻塞状态->等待t2线程执行完,->再次进入就绪态
(1)实例方法
(2)setPriority(int)设置线程的优先级,优先级取值 1 到 10,参数越大优先级越高。建议性的
(1)实例方法
(2)interrupt();设置线程中断的状态,但是不会真正的中断-->中断状态为true
isInterrupted();获得标志位,判断自己是否被人中断了,如果有人要中断我,我就自己中断一下我自己,但是不会清空标志位
interrupted();获得标志位,会清空标志位
(1)实例方法
强制终止一个线程
(1)实例方法
该线程不会单独执行, 当其他非守护线程都执行结束后, 自动退出【守护线程 也可以守护 main线程】
拓展
一、wait()方法和sleep()方法的区别
1、Object类中的wait()方法
(1)wait()方法是Object类中的方法,当线程执行到wait()方法时,它就进入到一个和该对象相关的等待池中,同时释放对象的机锁(暂时失去机锁,wait(long tiomeout)超过时间后还需返回对象锁);其他线程可以访问
(2)wait()使用notify或者notifyAll或者指定睡眠时间唤醒当前等待池中的线程。
(3)wait()必须放在synchronized block中。
(4)必须确保wait()在notify()/notifyAll()之前,不然会产生永远死锁的状态
2、Thread类中sleep()方法
调用sleep()方法的线程,会让出CPU进入阻塞状态,结束睡眠之后,进入就绪状态,sleep()睡眠时保持对象锁。
二、释放锁对象和不释放锁对象的情况:
1、释放对象锁
执行完同步代码块;
执行同步代码块过程中,遇到异常而导致线程终止,释放锁;
执行同步代码块过程中,执行了锁所属对象的wait()方法,释放锁进入对象的等待池;
2、不释放对象锁的方法
Thread.sleep()方法,放弃CPU,进入阻塞状态;
Thread.yield()方法,放弃CPU,进入就绪状态;
suspend()方法,暂停当前线程,已废弃;
线程同步编程(synchronized关键字)
1、为什么要使用同步机制
当多个线程去操作同一个数据时可能会出现数据混乱的问题,如何处理?? ==》同步原理
1.同步方法:
(1)普通成员方法:synchronized 修饰的方法 ex:public synchronized void test(){}
共享对象,默认是this(也就是当前类对象)
(2)静态成员方法:static synchronized 修饰的方法 ex:public static synchronized void test() {}
共享对象,默认是类的.class对象(也就是类的字节码对象)
2.同步代码块:
synchronized(共享对象){}
弊端:方法中的所有代码,都只允许一个线程访问。
2、编程步骤
(1)找到同步线程的共享对象
什么样的对象可以用作共享对象呢?
一般是共享的,并且只有一个的对象,比如:字节码对象、this、static修饰的对象、常量等等
(2)确定临界区:哪些代码在操作公有data
(3)在临界区上方用synchronized来拿一个共享对象的锁,临界区的下方会用 } 释放锁
线程间通信编程编程步骤
(1)找到同步线程的共享对象
(2)站到线程内部分析:每个线程单独分析,需要wait()还是notify()
(3)控制wait()发生在notify()之前:无固定模式
线程的死锁
A线程等待B线程持有的锁,B线程等待A线程持有的锁
public class DeadLockThreadTest {
private static String str1 = "筷子1";
private static String str2 = "筷子2";
public static void main(String[] args) {
// 使用匿名内部类的方式,继承Thread这个父类
new Thread() {
public void run() {
while (true) {
synchronized (str1) {
System.out.println(getName() + "拿到了" + str1 + "\t等待" + str2);
synchronized (str2) {
System.out.println(getName() + "拿到了"+ str2 + "开吃");
}
}
}
}
}.start();
new Thread() {
public void run() {
while(true) {
synchronized (str2) {
System.out.println(getName() + "拿到了" + str2 + "\t等待" + str1);
synchronized (str1) {
System.out.println(getName() + "拿到了" + str1 + "开吃");
}
}
}
}
}.start();
}
}