Java线程详解与锁的应用
1.线程的六种状态
1.新建状态(new 线程对象)
2.运行状态(等待CPU的执行资源)
3.受阻塞状态(等待CPU的执行资源)
4.休眠状态(调运sleep(时间)方法)
5.等待状态(调用了wait方法)
6.死亡状态(run方法执行完毕)
解析:创建一个线程相当于CPU开辟了一个独立的执行路径
每一个执行路径都是一个独立空间
2.两个线程的运行代码
public class text {
public static void main(String[] args) {
SubThread1 thread = new SubThread1();
thread.start();
for(int i = 0;i < 50; i++) {
System.out.println(Thread.currentThread().getName() + "--" + i);
}
}
}
class SubThread1 extends Thread{
@Override
public void run() {
for (int i = 0; i < 50; i++) {
System.out.println(Thread.currentThread().getName()+ "--" + i);
}
}
}
3.线程的第三种常见方式
匿名内部类方式
相当于创建了一个该类的子类对象
new 父类名称(){
重写父类的方法
}
这里new出来的就是这个类的子类对象
public class text {
public static void main(String[] args) {
Test1 test = new Test1() {
@Override
public void fun() {
System.out.println("我是子类 的fun方法");
}
};
test.fun();
}
}
class Test1{/创建父类
public void fun() {
System.out.println("我是父类的fun方法");
}
}
运行结果:
我是子类 的fun方法
4.内部类的使用方法
public class text {
public static void main(String[] args) {
TestInter inter = new TestInter() {
@Override
public void fun() {
System.out.println("我是实现类 的方法");
}
};
inter.fun();
new TestInter() {
@Override
public void fun() {
System.out.println("我是匿名实现类方法");
}
}.fun();
}}
interface TestInter{
public abstract void fun();
}
运行结果:
我是实现类 的方法
我是匿名实现类方法
4.利用匿名内部类方式给TreeSet集合中的学生对象 按年龄排序学生:姓名 年龄
import java.util.Comparator;
import java.util.TreeSet;
public class text {
public static void main(String[] args) {
Comparator<Student> comparator = new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return (o1.getAge() - o2.getAge() == 0) ? 1 : (o1.getAge() - o2.getAge());
}
};
TreeSet<Student> tree = new TreeSet<>(comparator);
tree.add(new Student("a",12));
tree.add(new Student("b",16));
tree.add(new Student("c",11));
tree.add(new Student("d",12));
System.out.println(tree);
}
}
student类
public class Student{
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
private String name;
private int age;
public Student() {
super();
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
5.使用内部类创建线程(两种方式)
public class text {
public static void main(String[] args) {
new Thread() {
@Override
public void run() {
System.out.println("我是创建线程方式1");
}
}.start();
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("我是创建线程方式2");
}
};
Thread t2 = new Thread(runnable);
Thread thread = new Thread( new Runnable() {
@Override
public void run() {
System.out.println("我是创建线程方式2");
}
});
t2.start();
}
}
6.线程休眠Thread.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);
}
}
}
7.同步锁synchronized(对象锁)
1.锁可以是任意对象 要保证锁的唯一性
2.多个线程使用的应该是同一把锁
3.synchronized(对象锁) {
操作的内容
}
4.Thread.yield();让线程放弃出去资源
8.设置三个线程进行抢票
public class text {
public static void main(String[] args) {
Titke titke = new Titke();
Thread thread0 = new Thread(titke);
Thread thread1 = new Thread(titke);
Thread thread2 = new Thread(titke);
thread0.start();
thread1.start();
thread2.start();
}
}
class Titke implements Runnable{
private int tit = 200;
private Object object = new Object();
@Override
public void run() {
while (true) {
synchronized (object) {
if (tit > 0) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "--抢到-- " + tit + "号");
tit--;
}else {
break;
}
}
Thread.yield();
}
}
}
6.1同步锁规则
1.线程与到锁就进代码块(并携带锁)当线程执行完代码中的代码把锁返还 线程没有锁的汇在代码外等着
public class Demo06 {
public static void main(String[] args) {
TitkesRunable1 runable = new TitkesRunable1();
Thread t1 = new Thread(runable);
Thread t2 = new Thread(runable);
Thread t3 = new Thread(runable);
t1.start();
t2.start();
t3.start();
}
}
class TitkesRunable1 implements Runnable{
private int titkes = 50;
private Object obj = new Object();
@Override
public void run() {
while (true) {
if (sellTikets()) {
break;
}
Thread.yield();
}
}
public synchronized boolean sellTikets() {
synchronized (this) {
if (titkes > 0) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "--" + titkes);
titkes--;
}else{
return false;
}
}
return false;
}
}
7.模拟线程死锁
*/
public class Demo07 {
public static void main(String[] args) {
DieLock dieLock = new DieLock();
Thread t1 = new Thread(dieLock);
Thread t2 = new Thread(dieLock);
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 ist = true;
@Override
public void run() {
while (true) {
if (ist) {
synchronized(LockA.Lock_A) {
System.out.println("if....Lock_A");
synchronized(LockB.Lock_B) {
System.out.println("if....Lock_B");
}
}
}else {
synchronized (LockB.Lock_B) {
System.out.println("else...Lock_B");
synchronized (LockA.Lock_A) {
System.out.println("else..Look_A");
}
}
}
ist = !ist;
}
}
}
7.jdk 1.5锁
Lock 接口
使用LOCK锁
lock.lock();
try{
写操作共享数据的代码
}finally{
lock.unlock();
}
好处:
1.接口实现创建线程的好处;避免了直接继承Thread类的局限性(避免单继承)
2.接口即插即用 减少类与类直接的联系(可以解耦)
public class Demo08 {
public static void main(String[] args) {
TitKes3 titKes3 = new TitKes3();
Thread t1 = new Thread(titKes3);
Thread t2 = new Thread(titKes3);
Thread t3 = new Thread(titKes3);
t1.start();
t2.start();
t3.start();
}
}
class TitKes3 implements Runnable{
private int titkets = 100;
private ReentrantLock lock = new ReentrantLock();
@Override
public void run() {
while (true) {
lock.lock();
try {
if (titkets > 0) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ":" + titkets);
titkets--;
}else {
break;
}
} finally {
lock.unlock();
}
Thread.yield();
}
}
}