数据安全问题的解决
1、同步代码块
(弊端:降低了运行效率)
格式:(锁--同一把锁)
synchronized(任意对象){
多条语句操作共享数据的代码
}
//sellTicket.java
private int tickets=100;
private Object obj=new Object();//设置同一把锁
public void run(){
while(true){//死循环
if(tickets>0){//实现卖票
//通过sleep()方法模拟出票时间
synchronized(obj){//new Object()表示任意对象
try{
Thread.sleep(100);
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在出售第"+tickets+"张票");
tickets--;
}
}
}
}
//sellTicketDemo.java
sellTicket t1=new sellTicket();
Thread d1=new Thread(t1,"窗口1");
Thread d2=new Thread(t2,"窗口2");
Thread d3=new Thread(t3,"窗口3");
d1.start();
d2.start();
d3.start();
同步方法--锁对象this
//sellTicket.java
public void run(){
private int tickets=100;
private Object obj=new Object();
private int x=0;
while(true){//死循环
if(x%2==0){
if(tickets>0){//实现卖票
//通过sleep()方法模拟出票时间
synchronized(obj){//new Object()表示任意对象
try{
Thread.sleep(100);
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在出售第"+tickets+"张票");
tickets--;
}
}
}else{
synchronized(obj){//new Object()表示任意对象
try{
Thread.sleep(100);
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在出售第"+tickets+"张票");
tickets--;
}
}
}
}
//sellTicketDemo.java
sellTicket t1=new sellTicket();
Thread d1=new Thread(t1,"窗口1");
Thread d2=new Thread(t2,"窗口2");
Thread d3=new Thread(t3,"窗口3");
d1.start();
d2.start();
d3.start();
同步静态方法--锁对象:类名.this
//sellTicket.java
public void run(){
private static int tickets=100;
private Object obj=new Object();
private int x=0;
while(true){//死循环
if(x%2==0){
if(tickets>0){//实现卖票
//通过sleep()方法模拟出票时间
synchronized(this){//this对象
try{
Thread.sleep(100);
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在出售第"+tickets+"张票");
tickets--;
}
}
}else{
sell();
}
}
}
private static synchronized void sell(){//方法
if(tickets>0){//实现卖票
//通过sleep()方法模拟出票时间
synchronized(obj){//new Object()表示任意对象
try{
Thread.sleep(100);
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在出售第"+tickets+"张票");
tickets--;
}
}
}
//sellTicketDemo.java
sellTicket t1=new sellTicket();
Thread d1=new Thread(t1,"窗口1");
Thread d2=new Thread(t2,"窗口2");
Thread d3=new Thread(t3,"窗口3");
d1.start();
d2.start();
d3.start();
同步静态方法(格式):
修饰符 static synchronized 返回值类型 方法名(方法参数){}
//类中都有synchronized
StringBuffer//线程安全,可变化的字符序列
Vector//可变化的对象数组
//对线程安全无要求的话,建议用ArrayList代替Vector
Hashtable
List<String> list=Collections.synchronizedList(new ArrayList<String>());
//可使得List变成线程安全类
//锁对象是一个接口
//方法
void lock();//获得锁
void unlock();//释放锁
//实现类
ReentrantLock类
//构造方法:
ReentrantLock();
//sellTicket.java
public void run(){
private int tickets=100;
while(true){//死循环
try{
lock.lock();//获得锁
if(tickets>0){//实现卖票
System.out.println(Thread.currentThread().getName()+"正在出售第"+tickets+"张票");
tickets--;
}
}finally{
lock.unlock();//释放锁
}
}
}
//sellTicketDemo.java
sellTicket t1=new sellTicket();
Thread d1=new Thread(t1,"窗口1");
Thread d2=new Thread(t2,"窗口2");
Thread d3=new Thread(t3,"窗口3");
d1.start();
d2.start();
d3.start();
//为了体现生产者和消费者之间的等待和唤醒,Java提供了几个方法,在Object类中
void wait();//导致当前线程等待,直到另一个线程调用该对象的notify()方法或notifyAll()方法
void notify();//唤醒正在等待对象监视器的单个线程
void notifyAll();//唤醒正在等待对象监视器的全部线程
//BoxDemo.java
public class BoxDemo{
public static void main(String[] args){
//创建奶箱对象
Box b=new Box();
//创建生产者对象
Producer p=new Producer(b);
//创建消费者对象
Customer c=new Customer(b);
//创建两个线程对象
Thread t1=new Thread(p);
Thread t2=new Thread(c);
//启动线程
t1.start();
t2.start();
}
}
//Box.java
public class Box{
private int milk;//第x瓶奶
private boolean state=false;//表示奶箱的状态
//定义两个方法,存储和获取牛奶
public synchronized void put(int milk){
if(state){//表示有牛奶,等待消费
try{
wait();
}catch(InterruptedException e){
e.printStackTrace();
}
}
//如果没有牛奶,进行生产
this.milk=milk;
System.out.println("送奶工将第"+this.milk+"瓶奶放入奶箱");
//生产完后
state=true;
//唤醒线程
notifyAll();
}
public synchronized void get(int milk){
if(!state){//没有牛奶,等待生产
try{
wait();
}catch(InterrupedException e){
e.printStackTrace();
}
}
//有牛奶,进行消费
this.milk=milk;
System.out.println("消费者取走第"+this.milk+"瓶奶");
//消费完成后,等待生产
state=false;
//唤醒线程
notifyAll();
}
}
//Producer.java
public class Producer implements Runnable{
private Box b;
public Producer(Box b){
this.b=b;
}
public void run(){
for(int i=1;i<=5;i++){
b.put(i);
}
}
}
//Customer.java
public class Customer implements Runnable{
private Box b;
public Customer(Box b){
this.b=b;
}
public void run(){
while(true){
b.get();
}
}
}
在网络通信协议下,实现网络互连的不同计算机上运行的程序间可以进行数据交换;
(实现信息共享)
手机扫一扫
移动阅读更方便
你可能感兴趣的文章