多线程序的角度理解静态类
通常称为嵌套类,当内部类是static时,意味着:
1 要创建嵌套类的对象,并不需要其外围类的对象
2 不能从嵌套类的对象中访问非静态的外围类对象(不能够从静态内部类的对象中访问外部类的非静态成员)
在创建静态内部类时不需要将静态内部类的实例绑定在外部类的实例上。普通非静态内部类的对象是依附在外部类对象之中的,要在一个外部类中定义一个静态的内部类,不需要利用关键字new来创建内部类的实例。静态类和方法只属于类本身,并不属于该类的对象,更不属于其他外部类的对象, 所以只能访问外部类的静态方法.
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch; public class InnerStaticClass { public static volatile int n = 0; // public Integer m = 0; final Integer lock = new Integer(1); static class MyThread1 implements Runnable { public static Integer locallock = new Integer(2); public static int value = 2; public static synchronized void inc() { n++; } public void run() { for (int i = 0; i < 1000; i++) try { System.out.println(this); // inc(); 方法一 // 方法二 // synchronized (lock){ // n = n + 1; // } // 方法三 // synchronized (this) { // n = n + 1; // } // 方法四 synchronized (locallock) { n = n + 1; } Thread.sleep(3); } catch (Exception e) { } } } public void runthread() throws InterruptedException { long beg = System.currentTimeMillis(); MyThread1[] mythreadary = new MyThread1[100]; Thread[] threadary = new Thread[100]; for (int i = 0; i < threadary.length; i++) { mythreadary[i] = new MyThread1(); // System.out.println(mythreadary[i].value); mythreadary[i].value = 32; threadary[i] = new Thread(mythreadary[i], "test1"); } for (int i = 0; i < threadary.length; i++) { threadary[i].start(); } for (int i = 0; i < threadary.length; i++) { threadary[i].join(); // System.out.println((mythreadary[i]).value); } System.out.println(InnerStaticClass.n); System.out.println(m); System.out.println("程序耗时: " + (System.currentTimeMillis() - beg)); } public static void main(String[] args) throws InterruptedException { InnerStaticClass tmp = new InnerStaticClass(); tmp.runthread(); } }
1 设置嵌套类的非静态方法,可以发现每个对象都互相独立的, 这和非静态方法一样
2 synchronized方法, 因为我们需要同步的数据是n, 属于静态类外部, synchronized 必须用在它的静态方法上,等于是该类的所有对象同步(方法一),或者用在代码块,对象必须使用外部变量 (方法二 ), 方法三 使用的是this, 也就是类对象本身,同步外部数据就会出现问题,该方法只使用于, 同一个静态类对象在不同线程间同步数据
3 通过测试发现,静态类和普通类的区别
1 可以不创建外部对象, 直接创建静态类, 它和任何对象没有依赖关系, 只和自身有依赖关系, 所以如果使用访问类外成员必须是静态成员, 非静态成员必须使用对象.成员来访问操作
2 静态类内部可以使用静态变量,如果使用同步方法静态变量,则会同步整个类,如果方法四,多个静态类对象在多个线程都会同步执行