java锁与同步基础入门.docx

上传人:b****6 文档编号:7067957 上传时间:2023-01-16 格式:DOCX 页数:16 大小:19.53KB
下载 相关 举报
java锁与同步基础入门.docx_第1页
第1页 / 共16页
java锁与同步基础入门.docx_第2页
第2页 / 共16页
java锁与同步基础入门.docx_第3页
第3页 / 共16页
java锁与同步基础入门.docx_第4页
第4页 / 共16页
java锁与同步基础入门.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

java锁与同步基础入门.docx

《java锁与同步基础入门.docx》由会员分享,可在线阅读,更多相关《java锁与同步基础入门.docx(16页珍藏版)》请在冰豆网上搜索。

java锁与同步基础入门.docx

java锁与同步基础入门

1同步

SellTiclet.java

packagecn.itcast_01;

importjava.util.concurrent.locks.Lock;

importjava.util.concurrent.locks.ReentrantLock;

publicclassSellTicketimplementsRunnable{

//定义票

privateinttickets=100;

//定义锁对象

privateLocklock=newReentrantLock();

@Override

publicvoidrun(){

while(true){

try{

//加锁

lock.lock();

if(tickets>0){

try{

Thread.sleep(100);

}catch(InterruptedExceptione){

e.printStackTrace();

}

System.out.println(Thread.currentThread().getName()

+"正在出售第"+(tickets--)+"张票");

}

}finally{

//释放锁

lock.unlock();

}

}

}

}

SellTicketDemo.java

packagecn.itcast_01;

/*

*虽然我们可以理解同步代码块和同步方法的锁对象问题,但是我们并没有直接看到在哪里加上了锁,在哪里释放了锁,

*为了更清晰的表达如何加锁和释放锁,JDK5以后提供了一个新的锁对象Lock。

*

*Lock:

*voidlock():

获取锁。

*voidunlock():

释放锁。

*ReentrantLock是Lock的实现类.

*/

publicclassSellTicketDemo{

publicstaticvoidmain(String[]args){

//创建资源对象

SellTicketst=newSellTicket();

//创建三个窗口

Threadt1=newThread(st,"窗口1");

Threadt2=newThread(st,"窗口2");

Threadt3=newThread(st,"窗口3");

//启动线程

t1.start();

t2.start();

t3.start();

}

}

2同步的弊端

DieLock.java

packagecn.itcast_02;

publicclassDieLockextendsThread{

privatebooleanflag;

publicDieLock(booleanflag){

this.flag=flag;

}

@Override

publicvoidrun(){

if(flag){

synchronized(MyLock.objA){

System.out.println("ifobjA");

synchronized(MyLock.objB){

System.out.println("ifobjB");

}

}

}else{

synchronized(MyLock.objB){

System.out.println("elseobjB");

synchronized(MyLock.objA){

System.out.println("elseobjA");

}

}

}

}

}

DieLockDome.java

packagecn.itcast_02;

/*

*同步的弊端:

*A:

效率低

*B:

容易产生死锁

*

*死锁:

*两个或两个以上的线程在争夺资源的过程中,发生的一种相互等待的现象。

*

*举例:

*中国人,美国人吃饭案例。

*正常情况:

*中国人:

筷子两支

*美国人:

刀和叉

*现在:

*中国人:

筷子1支,刀一把

*美国人:

筷子1支,叉一把

*/

publicclassDieLockDemo{

publicstaticvoidmain(String[]args){

DieLockdl1=newDieLock(true);

DieLockdl2=newDieLock(false);

dl1.start();

dl2.start();

}

}

MyLock.java

packagecn.itcast_02;

publicclassMyLock{

//创建两把锁对象

publicstaticfinalObjectobjA=newObject();

publicstaticfinalObjectobjB=newObject();

}

3资源类

GetThread.java

packagecn.itcast_03;

publicclassGetThreadimplementsRunnable{

privateStudents;

publicGetThread(Students){

this.s=s;

}

@Override

publicvoidrun(){

//Students=newStudent();

System.out.println(s.name+"---"+s.age);

}

}

SetThread.java

packagecn.itcast_03;

publicclassSetThreadimplementsRunnable{

privateStudents;

publicSetThread(Students){

this.s=s;

}

@Override

publicvoidrun(){

//Students=newStudent();

s.name="林青霞";

s.age=27;

}

}

Student,java

packagecn.itcast_03;

publicclassStudent{

Stringname;

intage;

}

StudentDemo.java

packagecn.itcast_03;

/*

*分析:

*资源类:

Student

*设置学生数据:

SetThread(生产者)

*获取学生数据:

GetThread(消费者)

*测试类:

StudentDemo

*

*问题1:

按照思路写代码,发现数据每次都是:

null---0

*原因:

我们在每个线程中都创建了新的资源,而我们要求的时候设置和获取线程的资源应该是同一个

*如何实现呢?

*在外界把这个数据创建出来,通过构造方法传递给其他的类。

*

*/

publicclassStudentDemo{

publicstaticvoidmain(String[]args){

//创建资源

Students=newStudent();

//设置和获取的类

SetThreadst=newSetThread(s);

GetThreadgt=newGetThread(s);

//线程类

Threadt1=newThread(st);

Threadt2=newThread(gt);

//启动线程

t1.start();

t2.start();

}

}

4序列流

GetThread.java

packagecn.itcast_04;

publicclassGetThreadimplementsRunnable{

privateStudents;

publicGetThread(Students){

this.s=s;

}

@Override

publicvoidrun(){

while(true){

synchronized(s){

System.out.println(s.name+"---"+s.age);

}

}

}

}

SetThread.java

packagecn.itcast_04;

publicclassSetThreadimplementsRunnable{

privateStudents;

privateintx=0;

publicSetThread(Students){

this.s=s;

}

@Override

publicvoidrun(){

while(true){

synchronized(s){

if(x%2==0){

s.name="林青霞";//刚走到这里,就被别人抢到了执行权

s.age=27;

}else{

s.name="刘意";//刚走到这里,就被别人抢到了执行权

s.age=30;

}

x++;

}

}

}

}

Student.java

packagecn.itcast_04;

publicclassStudent{

Stringname;

intage;

}

StudentDemo.java

packagecn.itcast_04;

/*

*分析:

*资源类:

Student

*设置学生数据:

SetThread(生产者)

*获取学生数据:

GetThread(消费者)

*测试类:

StudentDemo

*

*问题1:

按照思路写代码,发现数据每次都是:

null---0

*原因:

我们在每个线程中都创建了新的资源,而我们要求的时候设置和获取线程的资源应该是同一个

*如何实现呢?

*在外界把这个数据创建出来,通过构造方法传递给其他的类。

*

*问题2:

为了数据的效果好一些,我加入了循环和判断,给出不同的值,这个时候产生了新的问题

*A:

同一个数据出现多次

*B:

姓名和年龄不匹配

*原因:

*A:

同一个数据出现多次

*CPU的一点点时间片的执行权,就足够你执行很多次。

*B:

姓名和年龄不匹配

*线程运行的随机性

*线程安全问题:

*A:

是否是多线程环境是

*B:

是否有共享数据是

*C:

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

*解决方案:

*加锁。

*注意:

*A:

不同种类的线程都要加锁。

*B:

不同种类的线程加的锁必须是同一把。

*/

publicclassStudentDemo{

publicstaticvoidmain(String[]args){

//创建资源

Students=newStudent();

//设置和获取的类

SetThreadst=newSetThread(s);

GetThreadgt=newGetThread(s);

//线程类

Threadt1=newThread(st);

Threadt2=newThread(gt);

//启动线程

t1.start();

t2.start();

}

}

5线程运行

GetThread.java

packagecn.itcast_05;

/*

*分析:

*资源类:

Student

*设置学生数据:

SetThread(生产者)

*获取学生数据:

GetThread(消费者)

*测试类:

StudentDemo

*

*问题1:

按照思路写代码,发现数据每次都是:

null---0

*原因:

我们在每个线程中都创建了新的资源,而我们要求的时候设置和获取线程的资源应该是同一个

*如何实现呢?

*在外界把这个数据创建出来,通过构造方法传递给其他的类。

*

*问题2:

为了数据的效果好一些,我加入了循环和判断,给出不同的值,这个时候产生了新的问题

*A:

同一个数据出现多次

*B:

姓名和年龄不匹配

*原因:

*A:

同一个数据出现多次

*CPU的一点点时间片的执行权,就足够你执行很多次。

*B:

姓名和年龄不匹配

*线程运行的随机性

*线程安全问题:

*A:

是否是多线程环境是

*B:

是否有共享数据是

*C:

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

*解决方案:

*加锁。

*注意:

*A:

不同种类的线程都要加锁。

*B:

不同种类的线程加的锁必须是同一把。

*

*问题3:

虽然数据安全了,但是呢,一次一大片不好看,我就想依次的一次一个输出。

*如何实现呢?

*通过Java提供的等待唤醒机制解决。

*

*等待唤醒:

*Object类中提供了三个方法:

*wait():

等待

*notify():

唤醒单个线程

*notifyAll():

唤醒所有线程

*为什么这些方法不定义在Thread类中呢?

*这些方法的调用必须通过锁对象调用,而我们刚才使用的锁对象是任意锁对象。

*所以,这些方法必须定义在Object类中。

*/

publicclassStudentDemo{

publicstaticvoidmain(String[]args){

//创建资源

Students=newStudent();

//设置和获取的类

SetThreadst=newSetThread(s);

GetThreadgt=newGetThread(s);

//线程类

Threadt1=newThread(st);

Threadt2=newThread(gt);

//启动线程

t1.start();

t2.start();

}

}

SetThread.java

packagecn.itcast_05;

publicclassSetThreadimplementsRunnable{

privateStudents;

privateintx=0;

publicSetThread(Students){

this.s=s;

}

@Override

publicvoidrun(){

while(true){

synchronized(s){

//判断有没有

if(s.flag){

try{

s.wait();//t1等着,释放锁

}catch(InterruptedExceptione){

e.printStackTrace();

}

}

if(x%2==0){

s.name="林青霞";

s.age=27;

}else{

s.name="刘意";

s.age=30;

}

x++;//x=1

//修改标记

s.flag=true;

//唤醒线程

s.notify();//唤醒t2,唤醒并不表示你立马可以执行,必须还得抢CPU的执行权。

}

//t1有,或者t2有

}

}

}

Student.java

packagecn.itcast_05;

publicclassStudent{

Stringname;

intage;

booleanflag;//默认情况是没有数据,如果是true,说明有数据

}

StudentDemo.java

packagecn.itcast_05;

/*

*分析:

*资源类:

Student

*设置学生数据:

SetThread(生产者)

*获取学生数据:

GetThread(消费者)

*测试类:

StudentDemo

*

*问题1:

按照思路写代码,发现数据每次都是:

null---0

*原因:

我们在每个线程中都创建了新的资源,而我们要求的时候设置和获取线程的资源应该是同一个

*如何实现呢?

*在外界把这个数据创建出来,通过构造方法传递给其他的类。

*

*问题2:

为了数据的效果好一些,我加入了循环和判断,给出不同的值,这个时候产生了新的问题

*A:

同一个数据出现多次

*B:

姓名和年龄不匹配

*原因:

*A:

同一个数据出现多次

*CPU的一点点时间片的执行权,就足够你执行很多次。

*B:

姓名和年龄不匹配

*线程运行的随机性

*线程安全问题:

*A:

是否是多线程环境是

*B:

是否有共享数据是

*C:

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

*解决方案:

*加锁。

*注意:

*A:

不同种类的线程都要加锁。

*B:

不同种类的线程加的锁必须是同一把。

*

*问题3:

虽然数据安全了,但是呢,一次一大片不好看,我就想依次的一次一个输出。

*如何实现呢?

*通过Java提供的等待唤醒机制解决。

*

*等待唤醒:

*Object类中提供了三个方法:

*wait():

等待

*notify():

唤醒单个线程

*notifyAll():

唤醒所有线程

*为什么这些方法不定义在Thread类中呢?

*这些方法的调用必须通过锁对象调用,而我们刚才使用的锁对象是任意锁对象。

*所以,这些方法必须定义在Object类中。

*/

publicclassStudentDemo{

publicstaticvoidmain(String[]args){

//创建资源

Students=newStudent();

//设置和获取的类

SetThreadst=newSetThread(s);

GetThreadgt=newGetThread(s);

//线程类

Threadt1=newThread(st);

Threadt2=newThread(gt);

//启动线程

t1.start();

t2.start();

}

}

6

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 面试

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1