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

被折叠的 条评论
为什么被折叠?



