线程的状态
线程的六种状态
1.新建状态(new 线程对象)
2.运行状态(调用start方法)
3.受阻塞状态(等待CPU的执行资源)
4.休眠状态(调用了sleep(时间)方法)
5.等待状态(调用了wait方法)
6.死亡状态(run执行完毕)

匿名内部类
线程的第三种创建方式:
匿名内部类方式:相当于创建了一个该类的子类对象
new 父类或接口名(){
重写父类方法
};
这里new出来的就是这个类的子类对象
示例代码:
class Test{
public void fun() {
System.out.println("我是父类的fun方法");
}
}
public static void fun1() {
Test test = new Test() {
@Override
public void fun() {
System.out.println("我是子类的fun方法");
}
};
test.fun();
}
接口:
interface TestInter{
public abstract void fun();
}
public static void fun2() {
new TestInter() {
@Override
public void fun() {
System.out.println("我是实现类的fun方法");
}
}.fun();
}
需求:利用匿名内部类方式给TreeSet集合中的学生对象按年龄排序
TreeSet<Student> set = new TreeSet<>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.getAge() - o2.getAge();
}
});
set.add(new Student("sc", 18));
set.add(new Student("kd", 19));
set.add(new Student("kb", 17));
for (Student student : set) {
System.out.println(student);
}
匿名内部类创建线程
继承:
new Thread() {
@Override
public void run() {
System.out.println("-----");
}
}.start();
接口:
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("|||||");
}
};
new Thread(runnable).start();
合一起:
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("`````");
}
});
thread.start();
线程休眠
sleep()的作用是让当前线程休眠,即当前线程会从运行状态进入到休眠状态。
sleep()会指定休眠时间
代码示例:
public class Demo04 {
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 100; i++) {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + i);
}
}
}
class SleepThread extends Thread{
@Override
public void run() {
for (int i = 0; i < 50; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + i);
}
}
}
同步锁(同步代码块)
同步锁:锁可以是任意对象,要保证锁的唯一
同步锁规则:
线程遇到锁可以进入同步代码块(并且携带锁)
当线程执行代码块中的代码后 把锁返还
线程没有遇到锁 会在同步代码块外等待 遇到锁才能进
卖火车票问题:
public class Demo {
public static void main(String[] args) {
Tickets t = new Tickets();
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
Thread t3 = new Thread(t);
t1.start();
t2.start();
t3.start();
}
}
class Tickets implements Runnable{
private int tickets = 50;
private Object obj = new Object();
@Override
public void run() {
while (true) {
synchronized (obj) {
if (tickets > 0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "--" + tickets);
tickets--;
} else {
break;
}
}
Thread.yield();
}
}
}
在方法中添加synchronized关键词 把方法变成 同步方法
class Tickets1 implements Runnable{
private int tickets = 50;
private Object obj = new Object();
@Override
public void run() {
while (true) {
if (sellTickets()) {
break;
}
Thread.yield();
}
}
public synchronized boolean sellTickets() {
if (tickets > 0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "--" + tickets);
tickets--;
return false;
} else {
return true;
}
}
}
死锁
死锁:在编写多线程的时候,必须要注意资源的使用问题,如果两个或多个线程分别拥有不同的资源,
而同时又需要对方释放资源才能继续运行时,就会发生死锁。比如如果线程1持有锁A并且想获得锁B,线程2持有锁B并且想获得锁A,那么这两个线程将永远等待下去,产生了死锁
模拟线程死锁:
public class Demo07 {
public static void main(String[] args) {
DieLock dl = new DieLock();
Thread t1 = new Thread(dl);
Thread t2 = new Thread(dl);
t1.start();
t2.start();
}
}
class LockA {
private LockA() {
}
public static final LockA LOCK_A = new LockA();
}
class LockB {
private LockB() {
}
public static final LockB LOCK_B = new LockB();
}
class DieLock implements Runnable{
private boolean isTrue = true;
@Override
public void run() {
while (true) {
if (isTrue) {
synchronized (LockA.LOCK_A) {
System.out.println("LOCK_A");
synchronized (LockB.LOCK_B) {
System.out.println("LOCK_B");
}
}
} else {
synchronized (LockB.LOCK_B) {
System.out.println("LOCK_B");
synchronized (LockA.LOCK_A) {
System.out.println("LOCK_A");
}
}
}
isTrue = !isTrue;
}
}
}
Lock接口
JDK1.5 锁 Lock接口
使用Lock锁
lock.lock();
try{
写操作共享数据的代码
} finally {
lock.unlock();
}
接口实现创建线程好处:
1.避免直接继承Thread类的局限性(避免单继承)
2.接口即插即用 减少类与类之间的联系(可以解耦)
使用接口Lock接口锁:
public class Demo {
public static void main(String[] args) {
Tickets3 tickets3 = new Tickets3();
Thread t1 = new Thread(tickets3);
Thread t2 = new Thread(tickets3);
Thread t3 = new Thread(tickets3);
t1.start();
t2.start();
t3.start();
}
}
class Tickets3 implements Runnable{
private int tickets = 50;
private ReentrantLock lock = new ReentrantLock();
@Override
public void run() {
while (true) {
lock.lock();
try {
if (tickets > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "--" + tickets);
tickets--;
} else {
break;
}
} finally {
lock.unlock();
}
Thread.yield();
}
}
}