您的位置:首页 > 编程语言 > Java开发

Java线程详解与锁的应用

2018-02-06 22:38 330 查看

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() {//重写Thread的方法
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>() {//直接以Student类为泛型调用Comparator类

@Override
public int compare(Student o1, Student o2) {//重写comoarator方法

return (o1.getAge() - o2.getAge() == 0) ? 1 : (o1.getAge() - o2.getAge());//制定排序规则
}
};
TreeSet<Student>  tree = new  TreeSet<>(comparator);//创建Treeset集合泛型Student
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();
// TODO Auto-generated constructor stub
}
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) {
//1.匿名线程类Thread直接创建线程
new Thread() {
@Override
public void run() {
System.out.println("我是创建线程方式1");
}
}.start();
//2.通过Runnable类中转创建线程
Runnable runnable = new  Runnable() {

@Override
public void run() {
System.out.println("我是创建线程方式2");

}
};
Thread t2 = new Thread(runnable);
//3.综合中转方式创建线程
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);//线程休眠1秒 单位毫秒
System.out.println(Thread.currentThread().getName() + i);
}
}
}
class SleepThread extends Thread{
@Override
public void run() {
//如果子线程中出现异常 只能try ... catch处理
/*
* Thread 是 Runnable接口实现类
* 重写了接口中的 run方法
* 该接口 没有抛出异常
* 所有Runnable接口的实现类(包括Thread类)
* 都不能在run方法中 抛出异常只能处理
*
*/
for (int i = 0; i < 50; i++) {

try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
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();//1.创建线程中转类
Thread thread0 = new Thread(titke);//2.创建一个线程
Thread thread1 = new Thread(titke);
Thread thread2 = new Thread(titke);
thread0.start();//3.开启线程
thread1.start();
thread2.start();

}
}
class Titke implements Runnable{
private int tit = 200;
private Object object = new Object();
@Override
public void run() {//重写run方法
while (true) {
synchronized (object) {//设置锁使其必须执行完才能换线程接班
if (tit > 0) {
try {
Thread.sleep(50);//线程休眠50毫秒
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//有票次抢一张票
System.out.println(Thread.currentThread().getName() + "--抢到-- " + tit + "号");
tit--;
}else {
//没票结束
break;
}
}
Thread.yield();//线程放弃CPU资源
}

}
}


6.1同步锁规则

1.线程与到锁就进代码块(并携带锁)当线程执行完代码中的代码把锁返还 线程没有锁的汇在代码外等着


public class Demo06 {
public static void main(String[] args) {
//创建3条线程
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{
//保证票是共享数据 只new一次该类对象
private int titkes = 50;
//创建了对象锁保证了唯一
private Object obj = new Object();
//买票方法
@Override
public void run() {
while (true) {
if (sellTikets()) {
break;
}
Thread.yield();
}
}
//静态方法 同步代码块的锁可以使用本类 类名.class
//在方法中添加synchronized关键词 把方法变成同步方法
public synchronized boolean sellTikets() {
//操作的共享数据的代码
synchronized (this) {//锁只要保证对象和唯一就可以填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();
}

}
//创建AS锁
class LockA {
private LockA(){

}
//定义一个常量 锁对象 不能修改(不能创建)
public static final LockA Lock_A = new LockA();
}
//创建B锁
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类的局限
c36b
性(避免单继承)
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) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ":" + titkets);
titkets--;
}else {
break;
}
} finally {
//解锁
lock.unlock();
}
//让出CPU资源
Thread.yield();
}

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: