java并发编程--第二篇java线程

Java线程类也是一个object类,它的实例都继承自java.lang.Thread或其子类。编写线程运行时执行的代码有两种方式:一种是创建Thread子类的一个实例并重写run方法,第二种是创建类的时候实现Runnable接口。

1、创建Thread的子类

1.1、创建Thread子类的一个实例并重写run方法,run方法会在调用start()方法之后被执行。

public class MyThread extends Thread{
    public void run() {
        System.out.println("hello world");
    }
}

执行

MyThread myThread = new MyThread();
myTread.start();

1.2、创建一个Thread的匿名子类,并启动

Thread mythread = new Thread(){
    public void run() {
        System.out.println("hello world");
    }
};
mythread.start();

2、实现Runnable接口

2.1、创建实例实现Runnable接口

public class myRunnable implements Runnable{
    public void run() {
        System.out.println("hello world");
    }
}

执行

Thread mythread = new Thread(new myRunnable());
mythread.start();

2.2、创建一个实现Runnable接口的匿名类

 Runnable myRunnable = new Runnable() {
     public void run() {
        System.out.println("hello world");
     }
 };

3、竞态条件与临界区

当两个线程竞争同一资源时,如果对资源的访问顺序敏感,就称存在竞态条件。导致竞态条件发生的代码区称作临界区。

4、线程安全与共享资源

4.1、局部变量

局部变量存储在线程自己的栈中,因此,局部变量永远也不会被多个线程共享,是线程安全的。

4.2、局部的对象引用

对象的局部引用和基础类型的局部变量不太一样。尽管引用本身没有被共享,但引用所指的对象并没有存储在线程的栈内。所有的对象都存在共享堆中。如果在某个方法中创建的对象不会逃逸出(该方法,那么它就是线程安全的。实际上,哪怕将这个对象作为参数传给其它方法,只要别的线程获取不到这个对象,那它仍是线程安全的。

public void someMethod(){
  LocalObject localObject = new LocalObject();
  localObject.callMethod();
  method2(localObject);
}

public void method2(LocalObject localObject){
  localObject.setValue("value");
}

LocalObject对象没有被方法返回,也没有被传递给someMethod()方法外的对象。每个执行someMethod()的线程都会创建自己的LocalObject对象,并赋值给localObject引用。因此,这里的LocalObject是线程安全的。即使将LocalObject作为参数传给同一个类的其它方法或其它类的方法时,它仍然是线程安全的。当然,如果LocalObject通过某些方法被传给了别的线程,那它就不再是线程安全的了。

4.3、对象成员

对象成员存储在堆上。如果两个线程同时更新同一个对象的同一个成员,那这个代码就不是线程安全的。

public class NotThreadSafe{
    StringBuilder builder = new StringBuilder();

    public add(String text){
        this.builder.append(text);
    }   
}

如果两个线程同时调用同一个NotThreadSafe实例上的add()方法,就会有竞态条件问题

NotThreadSafe sharedInstance = new NotThreadSafe();

new Thread(new MyRunnable(sharedInstance)).start();
new Thread(new MyRunnable(sharedInstance)).start();

public class MyRunnable implements Runnable{
  NotThreadSafe instance = null;

  public MyRunnable(NotThreadSafe instance){
    this.instance = instance;
  }

  public void run(){
    this.instance.add("some text");
  }
}

改造为两个线程在不同的NotThreadSafe实例上调用add方法,变为线程安全的。

new Thread(new MyRunnable(new NotThreadSafe())).start();
new Thread(new MyRunnable(new NotThreadSafe())).start();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值