Java基础针对自己薄弱环节总结09(线程中)
来源:互联网 发布:幽默app软件下载 编辑:程序博客网 时间:2024/05/22 17:51
一、同步代码块、同步方法
1、同步代码块
synchronized(锁对象){
需要被锁的代码 //线程只有拿到了锁对象,才能执行这里的代码!!!换言之,这里的代码如果执行了,说明该 线程拿到了锁对象,其他线程不能拿到该锁对象
}
多个线程必须使用同一个锁对象,要不然锁无效
2、同步方法
public synchronized void show(){} //普通方法的锁是this public static synchronized void show(){} //静态方法的锁是当前类的字节码文件对象 类名.class3、注意问题
多个线程必须使用同一个锁对象,要不然锁无效
同步代码块锁可以是任意对象
同步方法的锁是this
静态方法的锁是当前类的字节码文件对象 类名.class
二、死锁
死锁原因:线程1占有着A锁,线程2拿着B锁,当线程1要用B锁,线程2要用A锁时,发生死锁。
代码体现
package cn.itcast.thread;/** * 线程1类 * @author LBK * */public class Thread01 extends Thread {@Overridepublic void run() {synchronized (Lock.LOCK_A) {System.out.println("我是线程1,我拿着锁A,现在需要拿锁B");synchronized (Lock.LOCK_B) {System.out.println("我是线程1,成功拿到锁B");}}}}
package cn.itcast.thread;/** * 线程2类 * @author LBK * */public class Thread02 extends Thread{@Overridepublic void run() {synchronized (Lock.LOCK_B) {System.out.println("我是线程2,我拿着锁B,现在需要拿锁A");synchronized (Lock.LOCK_A) {System.out.println("我是线程2,成功拿到锁A");}}}}
package cn.itcast.thread;/** * 锁类 * @author LBK * */public class Lock {public static final Object LOCK_A=new Object();public static final Object LOCK_B=new Object();}
package cn.itcast.thread;/** * 测试类 * @author LBK * */public class ThreadTest {public static void main(String[] args) {Thread01 t1=new Thread01();Thread02 t2=new Thread02();t1.start();t2.start();}}
结果:
右边红色证明程序一直没有停止,发生了死锁。(解决方案在这里先不说了,以后再和大家分享)
三、多个线程操作同一数据的问题(线程间的通讯问题)
其实就是多个线程同时操作同一个对象
卖票案例就是线程间通讯问题
下面是问题代码(因为没有对操作共享数据的代码加入同步代码块)
class Student { public String name; public int age; @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; }}class SetThread extends Thread{ private Student stu; public SetThread(Student stu){ this.stu = stu; } @Override public void run() { int i=0; while(true){ if(i%2 ==0){//执行%2操作,是为了写入不同的数据,测试在写入过程中,是否影响另一个线程的读取操作 stu.name = "张三"; stu.age = 13; }else{ stu.name = "李四"; stu.age = 14; } i++; } }}class GetThread extends Thread { private Student stu; public GetThread(Student stu){ this.stu = stu; } @Override public void run() { while(true){ System.out.println(stu); } }}public class Test { public static void main(String[] args) { //创建共享数据 Student stu = new Student(); //创建两个线程,并且让这两个线程同时操作这个共享数据 GetThread get = new GetThread(stu); SetThread set = new SetThread(stu); get.start(); set.start(); }}
结果:出现错误数据
错误原因:在SetThread刚做完if赋值时,GetThread抢到,开始执行,此时输出正确,但是当SetThread执行到else中的对年龄赋值时,GetThread抢到开始执行,输出的是张三 ,14。
解决方案1:加锁(把上面两个线程中的共享数据加锁,锁就是stu对象)
class SetThread extends Thread {private Student stu;public SetThread(Student stu) {this.stu = stu;}@Overridepublic void run() {int i = 0;while (true) {synchronized (stu) {if (i % 2 == 0) {// 执行%2操作,是为了写入不同的数据,测试在写入过程中,是否影响另一个线程的读取操作stu.name = "张三";stu.age = 13;} else {stu.name = "李四";stu.age = 14;}i++;}}}}class GetThread extends Thread {private Student stu;public GetThread(Student stu) {this.stu = stu;}@Overridepublic void run() {while (true) {synchronized (stu) {System.out.println(stu);}}}}
解决方案2:(等待唤醒机制)请看下篇分解
0 0
- Java基础针对自己薄弱环节总结09(线程中)
- Java基础针对自己薄弱环节总结08(线程上)
- Java基础针对自己薄弱环节总结10(线程下)
- Java基础针对自己薄弱环节总结05(API、集合)
- Java基础针对自己薄弱环节总结06(集合全)
- JAVA基础针对自己薄弱环节总结02(循环)
- JAVA基础针对自己薄弱环节总结01(循环之前的知识)
- Java基础针对自己薄弱环节总结03(面向对象封装、继承)
- Java基础针对自己薄弱环节总结04(面向对象多态)
- Java基础针对自己薄弱环节总结07(递归、IO流)
- D3D总结(针对自己的学习)
- java基础--线程总结
- Java总结--线程基础
- Java基础总结-线程
- JAVA基础知识点(自己总结的)
- JAVA基础知识点(自己总结的)
- JAVA基础知识点(自己总结的)
- JAVA基础知识点(自己总结的)
- ubuntu下修改文件夹权限
- shell syntax
- 【codeforces26A】Almost Prime
- usaco Agri-Net
- C++ 虚函数是否需要定义?
- Java基础针对自己薄弱环节总结09(线程中)
- CCF 201403-4无线网络 (二维最短路)
- [华为MU203] 使用AT命令实现网络访问
- Can't open framebuffer device /dev/fb0 ------[TQ2440-QT-first]
- 计算机系统结构的总体概述
- 9-4第二次简单实验
- uva1368 - DNA Consensus String
- linux怎样从vi退出到shell
- 马戏团叠罗汉-之最长递增子序列