Java 基础知识汇总 - 03

本文详细解析了Java中的多线程同步机制,包括synchronized关键字的应用及其对资源加锁的作用,以及如何避免线程冲突。此外,文章还深入探讨了Java内部类的基本用法,并对比了静态内部类的特性。

1.java中的字符串的长度和字节数

java中汉字占两个字节占2个字节,但字符串长度是1;英文字符(如A),占1个字节,长度是1,下面的例子能够说明.

2.java synchronized关键字

多线程的同步机制对资源进行加锁,使得在同一个时间,只有一个线程可以进行操作,同步用以解决多个线程同时访问时可能出现的问题,java是通过synchronized关键字来实现的。

当synchronized关键字修饰一个方法的时候,该方法叫做线程同步方法,简称同步方法;

当synchronized方法执行完或发生异常时,会自动释放锁.

下面的例子里面的Printer类有一个print()的方法,该方法是synchronized的,所以同时只能由一个线程去执行,所以,下面的结果应该是一个线程先输出0-9,然后再输出另一个线程的0-9.代码如下:

public class Hello {
	
	public static void main(String[] args) {
		Printer p = new Printer();

        Thread t1 = new MyThread(p);
        Thread t2 = new MyThread(p);

        t1.start();
        t2.start();
	}
}

class Printer
{
    public synchronized void Print()
    {
        for (int i = 0; i < 10; ++i)
        {
            try
            {
                Thread.sleep(500);
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() +" executing,print message:Hello: " + i);
        }
    }
}

class MyThread extends Thread
{
    private Printer p;

    public MyThread(Printer p)
    {
        this.p = p;
    }

    @Override
    public void run()
    {
    	
        p.Print();
    }
}

输出结果:

Thread-0 executing,print message:Hello: 0
Thread-0 executing,print message:Hello: 1
Thread-0 executing,print message:Hello: 2
Thread-0 executing,print message:Hello: 3
Thread-0 executing,print message:Hello: 4
Thread-0 executing,print message:Hello: 5
Thread-0 executing,print message:Hello: 6
Thread-0 executing,print message:Hello: 7
Thread-0 executing,print message:Hello: 8
Thread-0 executing,print message:Hello: 9
Thread-1 executing,print message:Hello: 0
Thread-1 executing,print message:Hello: 1
Thread-1 executing,print message:Hello: 2
Thread-1 executing,print message:Hello: 3
Thread-1 executing,print message:Hello: 4
Thread-1 executing,print message:Hello: 5
Thread-1 executing,print message:Hello: 6
Thread-1 executing,print message:Hello: 7
Thread-1 executing,print message:Hello: 8
Thread-1 executing,print message:Hello: 9

可以很清楚地看到,第一个线程先输出,等第一个线程先输出完,然后再输出第二个线程。那么如果不加synchronized关键字会怎么样呢?

public void Print()
    {
        for (int i = 0; i < 10; ++i)
        {
            try
            {
                Thread.sleep(500);
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() +" executing,print message:Hello: " + i);
        }
    }

输出结果如下:

Thread-1 executing,print message:Hello: 0
Thread-0 executing,print message:Hello: 0
Thread-1 executing,print message:Hello: 1
Thread-0 executing,print message:Hello: 1
Thread-0 executing,print message:Hello: 2
Thread-1 executing,print message:Hello: 2
Thread-0 executing,print message:Hello: 3
Thread-1 executing,print message:Hello: 3
Thread-1 executing,print message:Hello: 4
Thread-0 executing,print message:Hello: 4
Thread-1 executing,print message:Hello: 5
Thread-0 executing,print message:Hello: 5
Thread-0 executing,print message:Hello: 6
Thread-1 executing,print message:Hello: 6
Thread-0 executing,print message:Hello: 7
Thread-1 executing,print message:Hello: 7
Thread-0 executing,print message:Hello: 8
Thread-1 executing,print message:Hello: 8
Thread-0 executing,print message:Hello: 9
Thread-1 executing,print message:Hello: 9

可以看到两个线程在穿插进行地执行,每次输出的结果都不完全相同,这个取决于CPU对线程的调度情况。

另外,还有一种对执行的方法加锁的方式,具体如下:

public void Print(){
    	synchronized(this){
    	for (int i = 0; i < 10; ++i)
        {
            try
            {
                Thread.sleep(500);
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() +" executing,print message:Hello: " + i);
        }
    }
}

这样输出的结果和在方法上使用synchronized关键字进行修饰是一样的,不再赘述。

这里需要注意的是:当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块!!!

public class Hello {
	
	public static void main(String[] args) {
		Printer p = new Printer();

        Thread t1 = new MyThread(p);
        Thread t2 = new MyThread(p);

        t1.start();
        t2.start();
	}
}

class Printer
{
    public void Print()
    {
    	synchronized(this){
    		for (int i = 0; i < 10; ++i)
            {
                try
                {
                    Thread.sleep(500);
                }
                catch (InterruptedException e)
                {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() +" executing sync,print message:Hello: " + i);
            }
    	}
    	
    	for(int i = 0; i< 10;i++){
    		try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
    		System.out.println(Thread.currentThread().getName() +" executing none sync,print message:World: " + i);
    	}
    }
}

class MyThread extends Thread
{
    private Printer p;

    public MyThread(Printer p)
    {
        this.p = p;
    }

    @Override
    public void run()
    {
    	
        p.Print();
    }
}

输出结果:

Thread-0 executing sync,print message:Hello: 0
Thread-0 executing sync,print message:Hello: 1
Thread-0 executing sync,print message:Hello: 2
Thread-0 executing sync,print message:Hello: 3
Thread-0 executing sync,print message:Hello: 4
Thread-0 executing sync,print message:Hello: 5
Thread-0 executing sync,print message:Hello: 6
Thread-0 executing sync,print message:Hello: 7
Thread-0 executing sync,print message:Hello: 8
Thread-0 executing sync,print message:Hello: 9
Thread-1 executing sync,print message:Hello: 0
Thread-0 executing none sync,print message:World: 0
Thread-1 executing sync,print message:Hello: 1
Thread-0 executing none sync,print message:World: 1
Thread-0 executing none sync,print message:World: 2
Thread-1 executing sync,print message:Hello: 2
Thread-0 executing none sync,print message:World: 3
Thread-1 executing sync,print message:Hello: 3
Thread-0 executing none sync,print message:World: 4
Thread-1 executing sync,print message:Hello: 4
Thread-1 executing sync,print message:Hello: 5
Thread-0 executing none sync,print message:World: 5
Thread-1 executing sync,print message:Hello: 6
Thread-0 executing none sync,print message:World: 6
Thread-1 executing sync,print message:Hello: 7
Thread-0 executing none sync,print message:World: 7
Thread-1 executing sync,print message:Hello: 8
Thread-0 executing none sync,print message:World: 8
Thread-1 executing sync,print message:Hello: 9
Thread-0 executing none sync,print message:World: 9
Thread-1 executing none sync,print message:World: 0
Thread-1 executing none sync,print message:World: 1
Thread-1 executing none sync,print message:World: 2
Thread-1 executing none sync,print message:World: 3
Thread-1 executing none sync,print message:World: 4
Thread-1 executing none sync,print message:World: 5
Thread-1 executing none sync,print message:World: 6
Thread-1 executing none sync,print message:World: 7
Thread-1 executing none sync,print message:World: 8
Thread-1 executing none sync,print message:World: 9

这个结果有点冗长,仔细观察发现sync方法是线程0先执行,执行完了线程2才开始执行,而none sync方法穿插着执行,这个印证了上述结论。结论就是:

synchronized方法是一种粗粒度的并发控制,某一时刻,只能有一个线程执行该synchronized方法;
synchronized块则是一种细粒度的并发控制,只会将块中的代码同步,位于方法内、synchronized块之外的其他代码是可以被多个线程同时访问到的。

3.内部类

1)基本用法

public class HelloWorld {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		OutClass.InClass ic = new OutClass().new InClass();
		ic.print();
	}
}

class OutClass {
    private int age = 12;
    class InClass {
        public void print() {
            System.out.println(age);
        }
    }
}

还有一种内部类是静态内部类,只能访问外部类的静态变量!(注释里面的访问方式是不允许的!)

class Out {
    private static int age = 12;
    private int salary;
    static class In {
        public void print() {
            System.out.println(age);
            //System.out.println(salary);
        }
    }
}



 


 



 


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值