多线程安全问题

来源:互联网 发布:演技好的小鲜肉 知乎 编辑:程序博客网 时间:2024/05/05 05:33

1.产生的原因

1).线程任务中有处理的共享数据

2).线程任务中有多条对共享数据的操作

一个线程在操作共享数据的过程中,其他线程参与乐运算,造成了数据的错误

package cn.java.thread;public class SaleTicket implements Runnable {private int ticket = 1000;@Overridepublic void run() {// TODO Auto-generated method stubwhile (ticket > 0) {//让线程到这里稍停一会儿try {Thread.sleep(10);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println(Thread.currentThread().getName() + "......" + ticket--);}}public static void main(String[] args) {SaleTicket task =new SaleTicket();Thread t1 =new Thread(task);Thread t2 =new Thread(task);Thread t3 =new Thread(task);Thread t4 =new Thread(task);t4.start();t1.start();t2.start();t3.start();}}

执行此段程序会出现-1、-2的票,解决同步的问题,可以使用

synchronized(obj){

...

//此处同步代码就是代码块

}

public class SaleTicket implements Runnable {private int ticket = 1000;Object obj =new Object();@Overridepublic void run() {// TODO Auto-generated method stubwhile (ticket > 0) {//让线程到这里稍停一会儿synchronized(obj){try {Thread.sleep(10);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println(Thread.currentThread().getName() + "......" + ticket--);}}}

注意:synchronized中的锁对象不能new,必须使用同一个锁

下面是一个客户存钱的例子

public class Bank {private int sum;public void add(int n ){sum+=n;try {Thread.sleep(10);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println("sum"+sum);}}//顾客的存钱class Customer implements Runnable{private Bank bank =new Bank();@Overridepublic void run() {for (int i = 0; i <3; i++) {bank.add(100);}}}
public class AddCount {public static void main(String[] args) {// TODO Auto-generated method stubCustomer c =new Customer();Thread t1 =new Thread(c);Thread t2 =new Thread(c);Thread t3 =new Thread(c);t1.start();t2.start();t3.start();}}
执行时会出现同步错误,在add()方法中存在着对共享数据sum的操作。可以在add()方法上添加synchronized关键字实现同步,此时使用了this对象锁,如果是静态方法要实现synchronized同步的话,则使用了字节码文件对象锁,类名.class。


0 0
原创粉丝点击