22-多线程(二),线程的常用方法,线程安全(同步)
- 线程的优先级
- Thread.currentThread().getPriority() 获取当前线程的优先级
- Thread.MAX_PRIORITY 线程的最高优先级
- Thread.MIN_PRIORITY 线程的最低优先级
- Thread.NORM_PRIORITY 线程的默认优先级
public class MyRun implements Runnable { //具备线程操作能力
@Override
public void run() {
// TODO Auto-generated method stub
for (int i = 0; i <10; i++) {
System.out.println("当前线程对象: "+Thread.currentThread().getName()+"---"+i);
}
}
}
//线程的优先级
public class Test01 {
public static void main(String[] args) {
//[1]创建线程类对象
MyRun mr = new MyRun();
//Thread t = new Thread(mr);
//t.start();//启动线程
//[2]获取线程的优先级
System.out.println("主线程的有限级是: "+Thread.currentThread().getPriority());
System.out.println("线程的最高优先级: "+Thread.MAX_PRIORITY);
System.out.println("线程的最低优先级: "+Thread.MIN_PRIORITY);
System.out.println("线程的默认优先级是: "+Thread.NORM_PRIORITY);
//[3]设置线程的优先级
Thread t1 = Thread.currentThread();
t1.setPriority(2);
System.out.println(t1.getName()+":目前线程的优先级是:"+t1.getPriority());
System.out.println("=================");
Thread s = new Thread(mr);
//设置s线程的优先级为最高
s.setPriority(Thread.MAX_PRIORITY);
s.start();
System.out.println(s.getName()+": 目前的优先级是"+s.getPriority());
}
}
- 线程的状态
- isAlive()方法
- 判断线程是否在活动,如果是,返回true,否则返回false
public class Test02 {
public static void main(String[] args) {
//创建一个线程对象
MyRun mr = new MyRun();
Thread t = new Thread(mr);
System.out.println("线程启动前: "+t.isAlive());
System.out.println("==============");
t.start();
System.out.println("线程启动后: "+t.isAlive());
for (int i = 0; i < 5; i++) { //写在主方法中,主线程
System.out.println(Thread.currentThread().getName()+"----"+i);
}
System.out.println("当前线程状态: "+t.isAlive());
}
}
- 线程的强制执行
- 调用该方法的线程强制执行,其他线程处于阻塞状态,该线程执行完毕后,其他线程再执行
public class Test03 {
public static void main(String[] args) throws InterruptedException {
MyRun my = new MyRun(); //新生状态
Thread t = new Thread(my);
t.start(); //启动线程,就绪状态
for (int i = 0; i < 10; i++) { //写在主方法中,主线程
if(i==3) {
t.join(); //当前线程强制执行,主线程进入阻塞状态
}
System.out.println(Thread.currentThread().getName()+"--------"+i);
}
}
}
- 线程的休眠
- sleep: 使用当前正在执行的线程休眠,线程处于阻塞状态
public class MyRun02 implements Runnable{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("1.进入run方法..");
try {
Thread.sleep(1000);//线程休眠,进入阻塞状态
System.out.println("2.休眠结束...");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
System.out.println("3.睡眠被中断");
}
System.out.println("4.run方法正常结束");
}
}
public class Test04 {
public static void main(String[] args) {
MyRun02 my = new MyRun02();
Thread t = new Thread(my);
t.start();
//中断
t.interrupt();
}
}
- 线程的暂停: yield
- 当前正在执行的线程暂停一次,允许其他线程执行,不阻塞
- 线程直接进入就绪状态,如果没有其他线程等待执行,这个时候当前线程就会马上回复执行
public class MyRun03 implements Runnable{
@Override
public void run() {
// TODO Auto-generated method stub
for (int i = 0; i < 10; i++) {
System.out.println("当前线程对象: "+Thread.currentThread().getName()+i);
if(i==3) {
Thread.currentThread().yield();
System.out.println("当前线程礼让一次"); //礼让结束后进入就绪状态
}
}
}
}
public class Test05 {
public static void main(String[] args) {
MyRun03 my = new MyRun03();
Thread t = new Thread(my);
t.start();
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName()+"========"+i);
}
}
}
-
线程安全(同步):
-
1.同步代码块: 对共享资源进行上锁,锁的是含有共享资源的对象
-
2.同步的方法
同步线程的前提:
1. 必须有两个或者以上的线程 2. 必须是多个线程使用同一个资源的时候 3. 必须保证同步中只能有一个线程在运行
同步的缺点:
1. 死锁: 过多的同步会导致死锁,当双方都处于等待对方资源的时候,程序无法执行
-
public class MyTicket implements Runnable{
private int ticket = 5;
@Override
public void run() {
// TODO Auto-generated method stub
for (int i = 0; i < 100; i++) {
/*synchronized (this) { //小括号称之为同步监视器
}*/
show();
}
}
public synchronized void show() { //同步方法==>锁当前类的对象
if(ticket>0) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"买票: "+ticket--);
}
}
}
public class Test {
public static void main(String[] args) {
MyTicket mt = new MyTicket();
//创建一个线程类的对象,在堆中开辟一块空间,有一个属性ticket,值为5
//借助Tread类去启动线程
Thread s = new Thread(mt);
Thread s1 = new Thread(mt);
Thread s2 = new Thread(mt);
s.start();
s1.start();
s2.start();
}
}
- 案例,生产者,消费者和商品之间的案例
public class Goods {
private String brand; //品牌
private String name; //名称;
private boolean flag;
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//生产方法
public synchronized void set(String brand, String name) {
if(flag) { //falg的值为true的时候代表有商品,生产者等待,唤醒消费者flase
try {
super.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
this.brand = brand;
this.name = name;
flag = true;
super.notify();
}
//取走商品的方法
public synchronized void get() {
if(!flag) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("取走商品为: "+this.brand+"========="+this.name);
flag = false; //已经取走
super.notify(); //去唤醒生产者
}
}
public class Customer implements Runnable{
private Goods goods;
public Customer(Goods goods) {
super();
this.goods = goods;
}
@Override
public void run() {
// TODO Auto-generated method stub
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.goods.get();
}
}
}
public class Producer implements Runnable{
private Goods goods; //生产者生产商品
private boolean flag = true; //标志生产什么产品,让他交替执行
public Producer(Goods goods) {
super();
this.goods = goods;
}
@Override
public void run() {
// TODO Auto-generated method stub
for (int i = 0; i < 10; i++) {
if(flag) {
//同步对象
this.goods.set("卫龙", "辣条");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
flag = false;
}else {
this.goods.set("蒙牛", "红牛");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
flag = true;
}
}
}
}
public class Test {
public static void main(String[] args) {
//[1]创建共享资源对象
Goods goo = new Goods();
//[2]创建生产者对象
Producer pro = new Producer(goo);
//[3]创建消费者对象
Customer cus = new Customer(goo);
new Thread(pro).start();
new Thread(cus).start();
}
}