不共享数据的情况
package thread; class MyThread extends Thread{ private int count = 5; public MyThread(String name){ super(); this.setName(name); } public void run() { super.run(); while(count > 0) { count--; System.out.println("由"+this.currentThread().getName()+"计算,count="+count); } } } public class thread { public static void main(String[] args) { MyThread a = new MyThread("A"); MyThread b = new MyThread("B"); MyThread c = new MyThread("C"); a.start(); b.start(); c.start(); } }
一共创建了3个线程,每个线程都有自己的count变量,自己减少自己的count变量的值。这样的情况就是数据不共享。
共享数据的情况
共享数据的情况就是多个线程可以访问同一个变量。
package thread; class MyThread extends Thread{ private int count = 5; public void run() { super.run(); while(count > 0) { count--; System.out.println("由"+this.currentThread().getName()+"计算,count="+count); } } } public class thread { public static void main(String[] args) { MyThread mythread = new MyThread(); Thread a = new Thread(mythread,"A"); Thread b = new Thread(mythread,"B"); Thread c = new Thread(mythread,"C"); a.start(); b.start(); c.start(); } }
A,B,C线程打印出来的count值都是2,说明A,B,C同时对count进行出理,产生了“非线程安全”的问题。
要解决这个问题,需要在run方法前面加上synchronized关键字,使多个线程在执行run方法时,以排队的方式进行处理。当一个线程调用run前,先判断run方法有没有被上锁,如果上锁,说明有其他线程正在调用run方法,必须等其他线程调用完才可以执行run方法。这样也就实现了排队调用run方法的目的。synchronize可以在任意对象及方法上加锁,而加锁的这段代码成为“互斥区”或“临界区”。
package thread; class MyThread extends Thread{ private int count = 5; synchronized public void run() { super.run(); while(count > 0) { count--; System.out.println("由"+this.currentThread().getName()+"计算,count="+count); } } } public class thread { public static void main(String[] args) { MyThread mythread = new MyThread(); Thread a = new Thread(mythread,"A"); Thread b = new Thread(mythread,"B"); Thread c = new Thread(mythread,"C"); a.start(); b.start(); c.start(); } }