首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

线程不安全的缘故

2012-11-21 
线程不安全的原因?package ThreadTestpublic class ThreadTest {public static void main(String args[])

线程不安全的原因

?

package ThreadTest;public class ThreadTest {public static void main(String args[]){        MyThread mt = new MyThread() ;    // 定义线程对象           Thread t1 = new Thread(mt) ;    // 定义Thread对象        Thread t2 = new Thread(mt) ;    // 定义Thread对象        Thread t3 = new Thread(mt) ;    // 定义Thread对象        t1.start() ;        t2.start() ;        t3.start() ;    }}class MyThread implements Runnable{    private int ticket = 5 ;    // 假设一共有5张票    public void run(){//        synchronized (this){        while(ticket>0){                       try {                    Thread.sleep(300);                } catch (InterruptedException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }                System.out.println("卖票:ticket = " + ticket-- );            }//        }    }}

?

?

?

线程不安全条件

?

1 mt为一个对象实例

2 存在多个线程同时修改一个对象实例的属性,每个线程都有自己的临时空间用来保存对象实例的值,所以该值在被修改后不会马上同步到对象中,造成别的线程读到的不是对象实例最新的值,从而导致数据脏读,再造成脏写

?

运行结果如下

?

?

卖票:ticket = 5

卖票:ticket = 5

卖票:ticket = 4

卖票:ticket = 3

卖票:ticket = 2

卖票:ticket = 3

卖票:ticket = 1

卖票:ticket = 0

卖票:ticket = -1

?

?

?

修改: ?同步代码块,使一个时间里,只有一个线程可以访问该代码。从而保证数据的修改是单线程同步的

?

?

class MyThread implements Runnable{    private int ticket = 5 ;    // 假设一共有5张票    public void run(){        synchronized (this){        while(ticket>0){                try {                    Thread.sleep(300);                } catch (InterruptedException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }                System.out.println("卖票:ticket = " + ticket-- );            }        }    }}卖票:ticket = 5卖票:ticket = 4卖票:ticket = 3卖票:ticket = 2卖票:ticket = 1
?

?? ? ? ?synchronized (this){

}

同步的是一个属性,而不是代码段(而this 代表了本类,即此时本类中的别的方法也被同步?)

?

?

改进 ?用byte[] lock = {0}; 代替this. 比较省内存

?

class MyThread implements Runnable{    private int ticket = 5 ;    // 假设一共有5张票    private byte[] lock = {0};    public void run(){        synchronized (lock){        while(ticket>0){                try {                    Thread.sleep(300);                } catch (InterruptedException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }                System.out.println("卖票:ticket = " + ticket-- );            }        }    }}

?

或者直接synchronized ?多线程访问修改的属性 ?synchronized的是数组

?

class MyThread implements Runnable{    private int[] ticket = {5} ;    // 假设一共有5张票    public void run(){    synchronized(ticket){    sale();    }    }    private void sale(){     while(ticket[0]>0){             try {                 Thread.sleep(300);             } catch (InterruptedException e) {                 // TODO Auto-generated catch block                 e.printStackTrace();             }             System.out.println("卖票:ticket = " + ticket[0]-- );         }    }}
?

?

2 同步方法

?

?

?

class MyThread implements Runnable{    private  int ticket = 5 ;    // 假设一共有5张票    public void run(){    sale();    }    private synchronized void sale(){     while(ticket>0){             try {                 Thread.sleep(300);             } catch (InterruptedException e) {                 // TODO Auto-generated catch block                 e.printStackTrace();             }             System.out.println("卖票:ticket = " + ticket-- );         }    }}
?

?

?

?

?

?

?

?

以下为线程安全的,但是继承Thread类后,资源(ticket )没有共享,各自卖各自的票。而实现runnable接口是可以资源共享的

?

package ThreadTest;public class ThreadTestFirst {public static void main(String args[]){MyThreadF a = new MyThreadF("a");MyThreadF b = new MyThreadF("b");a.start();b.start();    }}class MyThreadF extends Thread{    private int ticket = 5 ;    // 假设一共有5张票    private String name;    public MyThreadF(String name) {this.name = name;}    public void run(){        while(ticket>0){                       try {                    Thread.sleep(300);                } catch (InterruptedException e) {                    e.printStackTrace();                }                System.out.println(this.name  + "卖票:ticket = " + ticket-- );            }    }}

?

?

a卖票:ticket = 5b卖票:ticket = 5b卖票:ticket = 4a卖票:ticket = 4b卖票:ticket = 3a卖票:ticket = 3b卖票:ticket = 2a卖票:ticket = 2a卖票:ticket = 1b卖票:ticket = 1
?

?

热点排行