java枷锁_JAVA基础9(多线程1)

1:多线程

(1)线程是依赖于进程而存在的。

A.进程正在运行的应用程序

B.线程进程的执行路径,执行单元

(2)多线程的两种方案:

继承Thread类:

实现Runable接口:

public class MyThread implements Runnable{

//实现runnable接口

public void run() {

//启动该线程对象之后,需要执行的代码

for (int i = 0; i < 10; i++) {

System.out.println(i);

}

}

}

public class MyThread extends Thread{

//1.继承Thread类

//2.重写run方法

public void run() {

//开启该线程之后,执行一个for循环

for (int i = 0; i < 10; i++) {

System.out.println(i);

}

}

}

(3)多线程的几个问题:

A.启动线程的方法

start()

B.start()和run()的区别

start():1.开启线程  2.执行run()方法里面的代码

run():执行的是线程里面执行的代码,并不会开启线程

C.重写run()

因为每个线程需要执行的代码都是都是不一样的,

我们需要将每个线程自己独立执行的代码写到run()方法中执行

D.线程不可以多次启动

(4)线程的调度和控制

线程休眠(Thread.sleep(毫秒值))

线程名称(setName(),getName();)

线程的调度及优先级setPriority(10)(注意默认值是5,区间在1-10之间)

线程优先级:设置抢占cpu执行权抢占到的概率

(5)多线程案例(两种方式实现,睡一会出现线程安全问题):

继承Thread卖票

实现Runnable卖票(睡一会出现线程安全问题)

按照真实的情景加入了延迟,出现了两个问题:

A.相同的票卖了多次

CPU的一次操作必须是原子性的(操作是CPU执行一次就可以直接完成的)

B.出现了负数的票

随机性和延迟导致的

出现上面的问题称为线程安全问题。

public class MyThread extends Thread{

//共有100张票,将ticket改为静态之后,被类的所有对象所共享

static int ticket = 100;

public void run() {

//用一个while true循环模拟三个窗口一直处于打开的状态

while (true) {

//只有当ticket>0的时候,才可以出售票

if (ticket>0) {

System.out.println(getName()+"正在出售第:"+ticket--+"张票");

}

}

}

}

public class Test {

public static void main(String[] args) {

//创建三个线程模拟三个售票窗口

MyThread mt1 = new MyThread();

MyThread mt2 = new MyThread();

MyThread mt3 = new MyThread();

//给线程设置名称

mt1.setName("窗口一");

mt2.setName("窗口二");

mt3.setName("窗口三");

//启动线程,开启售票

mt1.start();

mt2.start();

mt3.start();

}

}

(6)多线程安全问题

A.是否是多线程环境

B.是否有共享数据

C.是否有多条语句操作共享数据

(7)如何解决多线程安全问题

线程安全执行效率就低

A.同步代码块(测试不是同一个锁的情况,测试是同一个锁的情况)

synchronized(对象) {

需要被同步的代码。

}

B.两个问题:1.对象是什么 ?

答:任意对象 ,相当于是一把锁,只要线程进去就把锁锁上

2.需要同步的代码?

答:被线程执行的代码

C.锁对象问题

a.同步代码块(定义一个抽象类,里面专门定义一个锁)

任意对象

b.同步方法(仅适用于实现runable接口)

public synchronized voidsellTicket(){同步代码}

this

c.静态同步方法

类的字节码对象

public static synchronized voidsellTicket() {

需要同步的代码

}

public class MyThread implements Runnable{

//定义100张票

int ticket = 100;

Object obj = new Object();

public void run() {

while (true) {

//同步代码块

synchronized (obj) {//3个线程才可以共享同一把锁

if (ticket>0) {

//考虑到实际,我们需要给每一个线程加入一定的延迟,模拟一下这种效果

try {

Thread.sleep(100);

/**

* 分析:为什么会出现两张100张票

* t1抢占到cpu的执行权,此时ticket=100,但是此刻休眠了

* 此时被t2抢占到了cpu的执行权,此时ticket=100,

* t1,t2分别睡了100毫秒之后,分别醒来了

* t1此时出售第100张票

* t2此时出售第100张票

*/

/**

* 分析:为什么会出现0张票和-1张票

* 假设此时票池中仅剩1张票了,

* t1进来休眠了

* t2进来休眠了

* t3进来休眠了

*/

} 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) {

//创建MyThread对象

MyThread mt = new MyThread();

//创建三个窗口

Thread t1 = new Thread(mt);

Thread t2 = new Thread(mt);

Thread t3 = new Thread(mt);

//给每一个窗口设置姓名

t1.setName("窗口一");

t2.setName("窗口二");

t3.setName("窗口三");

//开启窗口进行售票

t1.start();

t2.start();

t3.start();

}

}

(8)匿名内部类的方式使用多线程

new Thread() {

public void run() {

...

}

}.start();

new Thread(new Runnable(){

public void run() {

...

}

}).start();

(9) JDK5的Lock锁,我们之前造的所有的锁都没有手动释放锁

static Lock lock = new ReentrantLock();

枷锁:lock.lock();

释放锁:lock.unlock();

可以让我们明确的知道在哪里加锁和释放锁。

依然写一个卖票的demo,用lock枷锁释放锁,

为了保证我们创建的锁一定会被释放,用一下代码进行改进

try{....}finally{.....}

(10)死锁问题

同步嵌套,锁里面套了一个锁,出现同步嵌套

(11)线程等待和唤醒机制

锁对象调用wait()锁对象调用notify()

注意:

wait和sleep的区别

线程等待,在等待的同时释放锁,而sleep()方法在执行的过程中是不会释放锁的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值