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

Java多线程基础(二)

2020-07-21 04:13 423 查看

一.线程的休眠、阻塞
让当前线程休眠,即当前线程会从“运行状态”进入到“休眠(阻塞)状态”。

Thread.sleep(1000)//休眠1000ms,即1s

线程的阻塞

在某一时刻某一个线程在运行一段代码的时候,这时候另一个线程也需要运行,但是在运行过程中的那个线程执行完成之前,另一个线程是无法执行。
也称为耗时操作,可以简单理解为:所有消耗时间的操作。如常见的文件读取、用户输入

二.线程的中断
一个线程是一个独立的执行路径,它是否应该结束,应该由其自身决定。

实例演示:

Thread thread1 = new Thread(new MyRunnable());
thread1.start();
for (int i=0;i<=5;i++){
System.out.println(Thread.currentThread().getName()+":我是一只小猫咪"+i);
try {
Thread.sleep(1000);
}catch (InterruptedException e){
e.printStackTrace();
}
}
//线程1添加中断标记
thread1.interrupt();
public class MyRunnable implements Runnable{
@Override
public void run() {
for (int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName()+":我是一只大老虎"+i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
//e.printStackTrace();
System.out.println("啊我要被中断了,我嚣张不了了");
return;
}
}
}

三.线程安全问题
如果有多个线程同时访问一个变量,那么很可能出现安全问题,抢占时间片,出现不合理的情况。

解决方案1:同步代码块(隐式锁)

线程同步:排队机制
格式:synchronized(锁对象){}
注意:要看同一把锁才会有效

实例演示:

public class MyRunnable implements Runnable{
private int count = 10;
private Object o = new Object();
@Override
public void run() {
while(true){
synchronized (o){
if(count>0){
for(int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName()+"正在卖票中");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}

count--;
System.out.println("已成功出票,余票为:"+count);
}
}
else{
break;
}

}
}
Runnable run = new MyRunnable();
new Thread(run).start();
new Thread(run).start();
new Thread(run).start();

使用synchronized锁住对象,当有线程被锁住之后其他线程不能进入执行。

解决方案2:同步方法(隐式锁)

在方法前面加上关键字synchronized
锁对象是this 如果是static方法,锁对象就是类名.class
注意:如果一个类里有多个同步方法,锁也只有一个
public class MyRunnable implements Runnable{
private int count = 10;
public synchronized boolean Ticket(){
if(count>0){
for(int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName()+"正在卖票中");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}

count--;
System.out.println("已成功出票,余票为:"+count);
}
return true;
}
return false;
}
}

解决方案3:显示锁 Lock子类 ReentranLock

显示锁更能体现锁的概念
public class MyRunnable implements Runnable{
private int count = 10;
private Lock lock = new ReentrantLock();
@Override
public void run() {
while(true){
lock.lock();//关锁
if(count>0){
for(int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName()+"正在卖票中");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}

count--;
System.out.println("已成功出票,余票为:"+count);
}
}
else{
break;
}
lock.unlock();//执行完毕,开锁
}
}
}

四.公平锁与非公平锁
公平锁:先来先到 排队 锁解开时谁先来谁先执行
不公平锁:谁抢到谁先执行

private Lock lock = new ReentrantLock(fair:true);
设置为true则是公平锁

死锁问题:

线程死锁是指由于两个或者多个线程互相持有对方所需要的资源,导致这些线程处于等待状态,无法前往执行。避免死锁发生,在任何有可能产生死锁的方法里,不能再调用产生其他锁的方法
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: