——————————————————————————————————–
1,创建线程
如何创建一个线程:
两种方式:
1. 自定义一个类继承Thread类,那么这个类就可以看做是一个多线程类
2. 要求【重写】Thread类里面的run方法,把需要执行的自定义线程代码放入这run方法
2,线程中的常用方法:
Thread(String name); 初始化线程的名字,属于线程的一个有参数的构造方法
setName(String name); 修改线程的名字
getName(); 获取线程的名字
static sleep(); static静态方法,通过Thread类名调用,这里需要处理一些异常,要求当前线程睡觉多少毫秒【哪一个线程执行了sleep方法,哪一个线程就睡觉】
static currentThead(); static静态方法,返回当前的线程对象【哪一个线程执行了currentThread方法,就返回哪一个线程对象】
getPriority(); 返回当前线程的优先级 CPU执行的优先级,不是绝对的
setPriority(int newPriority); 设置线程的优先级
【注意】
线程的优先级范围是从1 ~ 10, 10最高,1最低这里的优先级只是提高了当前线程拥有CPU执行权概率,并不能完全保证当前线程能够一定会占用更多的CPU时间片
线程的默认优先级为5
Thread[main,5,main]
Thread[Thread-0,5,main]
Thread[线程名, 优先级, 线程组名]
public class Demo2 extends Thread implements A{
public Demo2(String name) {
super(name);
}
@Override
public void testA() {
//这里也无法抛出异常,两种处理方法,第一种,捕获异常,第二种,在接口中声明方法部分,声明该异常
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void run() {
//这里是Demo2线程对象的线程代码
// TODO Auto-generated method stub
System.out.println(“28:” + Thread.currentThread());
for (int i = 0; i
System.out.println(“自定义线程”);
/* 在其他方法中, 使用sleep方法,可以抛出,可以捕获,但是在run方法为什么只有捕获没有抛出
这是一个语法规则:在Java中,重写父类的方法,要求和父类的方法声明一模一样,在Thread类中run方法没有抛出异常,所以在子类中,你也不能抛出异常,要和父类一致
*/
try {
sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) throws InterruptedException {
//这里是main线程
Demo2 d = new Demo2(“狗蛋”);
d.setName(“狗娃”);
d.setPriority(10);
//d.setName(“狗子”);
//System.out.println(d.getName());
d.start(); //开启自定义线程,执行自定义线程中的run方法里面的功能
System.out.println(“39:” + Thread.currentThread());
for (int i = 0; i
System.out.println(“这里是main线程”);
sleep(100);
}
}
}
3,线程的共享资源问题
处理方式:
上锁,锁门
Java中的线程同步机制:
方式1:
同步代码块:
格式:
synchronized (锁对象) {
需要同步的代码;
}
同步代码块的注意事项:
1. 锁对象,可以是任意的一个对象, 但是必须是同一个对象!!!不能在这里使用new 来创建匿名对象
2. sleep() 不会释放锁对象,不会开锁。例如: 厕所有人关门睡着了
3. 使用synchronized 同步代码块的时候,必须是真正意义上存在共享资源的线程问题,才会使用而且通常情况下,用synchronized锁住的代码越少越好,提高代码执行效率
class SaleTicket extends Thread {
private static int ticket = 50;
public SaleTicket(String name) {
super(name);
}
@Override
public void run() {
while (true) {
synchronized (“你好”) { //”你好 ” new Demo3()
if (ticket > 0) {
System.out.println(Thread.currentThread().getName()+”:卖出来第” + ticket
+ “张票”);
try {
sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
System.out.println(“卖完了”);
break;
}
ticket–;
}
}
}
}
public class Demo3 {
public static void main(String[] args) {
SaleTicket s1 = new SaleTicket(“窗口1”);
SaleTicket s2 = new SaleTicket(“窗口2”);
SaleTicket s3 = new SaleTicket(“窗口3”);
s2.start();
s1.start();
s3.start();
}
}
4,开发中的死锁现象
为什么会出现死锁: 【必须会】
1. 存在两个或两个以上的共享资源
2. 存在两个或者两个以上的线程使用这些共享资源
绝对不能用死锁!!!
class DeadLock extends Thread {
public DeadLock(String name) {
super(name);
}
@Override
public void run() {
if (Thread.currentThread().getName().equals(“小胖”)) {
synchronized (“电池”) {
System.out.println(“小胖有电池,想要遥控器”);
synchronized (“遥控器”) {
System.out.println(“小胖拿到了遥控器,打开了投影仪”);
}
}
} else if (Thread.currentThread().getName().equals(“逗比”)) {
synchronized (“遥控器”) {
System.out.println(“逗比有遥控器,想要电池”);
synchronized (“电池”) {
System.out.println(“逗比拿到了电池,打开了投影仪”);
}
}
}
}
}
public class Demo4 {
public static void main(String[] args) {
DeadLock d1 = new DeadLock(“小胖”);
DeadLock d2 = new DeadLock(“逗比”);
d1.start();
d2.start();
}
}
5,推荐方法
/*
Java语言是一种单继承,多实现【遵从】面向对象的语言
自定义线程的方式:
方式1:
1. 自定义一个类,继承Thread类
2. 重写Thread里面的run方法,把线程的功能代码放入到run方法中
3. 创建自定义线程类对象
4. 开启线程,使用start方法
弊端:
因为Java是一个单继承的语言,一旦某一个类继承了Thread类,就无法再继承其他类,或者说
一个类继承了其他类,也就没有办法继承Thread类
方式2: 【墙裂推荐】 【遵从】Runnable接口实现自定线程类
1. 自定义一个类,【遵从】Runnable接口
2. 实现Runnable接口中唯一要求的方法 Run方法,把线程的功能代码写入到run方法中
3. 创建Thread类对象,并且把【遵从】Runnable接口的自定义类对象,作为参数传入到Thread构造方法中
4. 调用Thread类对象的start方法,开启线程
*/
class TestRunnable implements Runnable {
//实现自定义线程类,遵从Runnable接口要求实现的Run方法,把线程代码写入到Runnable里面
@Override
public void run() {
for (int i = 0 ; i
System.out.println(“当前线程为:” + Thread.currentThread());
}
}
}
public class Demo5 {
public static
//创建Thread类对象,调用Thread构造方法中,需要传入Runnable接口实现类对象的方法~
Thread t1 = new Thread(new TestRunnable());
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i
System.out.println(“匿名内部类的匿名对象,作为方法的参数,这里是作为线程对象的参数” +
Thread.currentThread());
}
}
});
t1.start();
t2.start();
守护线程(后台线程)
例如:
软件的Log日志文件,软件的自动更新,软件的自动下载
特征:
如果整个程序再运行过程中,只剩下一个守护线程,那么这个守护线程也就没有意义了,会自动停止
JVM的垃圾回收机制是守护线程还是普通线程
守护线程!!!
6,线程通讯:
一个线程完成任务之后,通知另一个线程来完成该线程应该执行的任务
生产者和消费者问题
这里商品是两个线程直接的共享资源
wait(); 等待,如果一个线程执行了wait方法,那么这个线程就会进入临时阻塞状态,等待唤醒,这个唤醒必须
其他线程调用notify() 方法唤醒
notify(); 唤醒,唤醒线程池中进入【临时阻塞状态】的一个线程
注意事项:
1. wait()和notify()这两个方法都是Object类的方法
class Product {
String name; //商品的名字
int price; //价格
boolean flag = false; //产品是否生产成功,如果成功flag设置为true,消费者购买之后,设置为false
}
class Producer extends Thread {
Product p; //商品的类对象,是和消费者之间的共享资源
public Producer(Product p) {
this.p = p;
}
@Override
public void run() {
int count = 0;
while (true) {
synchronized (p) {
try {
sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (!p.flag) { //p.flag == false
//商品不存在,生产过程
if (count % 2 == 0) {
p.name = “红辣椒擀面皮”;
p.price = 5;
} else {
p.name = “唐风阁肉夹馍”;
p.price = 10;
}
count++;
System.out.println(“生产者生产了:” + p.name + “:” + p.price);
p.flag = true;
//生产结束,唤醒消费者
p.notify();
} else {
//商品存在,要求消费者来购买,生产者进入临时阻塞
try {
p.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} // try – catch
}// if – else
} // 同步代码块
}// while (true)
} //run()
}
class Customer extends Thread {
Product p; //商品类对象,是和生产者之间的共享资源
public Customer(Product p) {
this.p = p;
}
@Override
public void run() {
while (true) {
synchronized (p) {
try {
sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (p.flag) { //p.flag == true
//这里表示商品存在
System.out.println(“消费者购买了:” + p.name + “:” + p.price);
p.flag = false; //表示消费者购买完毕,要求生产者生产
//需要唤醒生产者
p.notify();
} else {
try {
//商品不存在,消费者进入临时阻塞
p.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} // try – catch
}// if – else
} //同步代码块
} // while (true)
} //run()
}
public class Demo7 {
public static void main(String[] args) {
Product product = new Product();
Producer p = new Producer(product);
Customer c = new Customer(product);
p.start();
c.start();
}
}
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!