实战java高并发程序设计(二、Java并行程序基础)

二、Java并行程序基础

2.1新建线程:

        Thread thread = new Thread();
        thread.start();

调用start()方法后自动调用run()方法,但线程新建时不能直接调用run()方法。

public class Client {
    public static void main(String[] args) {
        Thread thread = new Thread(){
            @Override
            public void run(){
                System.out.println("run()...");
            }
        };
        thread.start();
    }
}

2.2注意:不要随便使用stop()结束一个进程,stop()方法会直接终止进程,并释放这个进程所持有的锁,容易导致不同的线程读错数据。

结束进程的方法:

public class Client extends Thread{
    volatile boolean stopme = false;

    public void Stopme(){
        stopme = true;
    }

    @Override
    public void run(){
        while (true){
            if (stopme){
                System.out.println("exit by stopme");
                break;
            }
        }
    }
}

2.3中断进程

    public void Thread.interrupt(); //中断进程,设置中断标志,但不会强制中断
    public boolean Thread.isInterrupted();  //检查中断标志判断是否中断
    public static boolean Thread.interrupt();   //判断是否被中断,并清除当前中断状态

2.4wait()和notify()

public class Client {
    final static Object object = new Object();

//    等待
    public static class Thread1 extends Thread{
        @Override
        public void run(){
            synchronized (object){
                System.out.println(System.currentTimeMillis()+":T1 start!");
                try {
                    System.out.println(System.currentTimeMillis()+":T1 wait for Object!");
                    object.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(System.currentTimeMillis()+":T1 end!");
            }
        }
    }

//    唤醒等待线程
    public static class Thread2 extends Thread{
        @Override
        public void run(){
            synchronized (object){
                System.out.println(System.currentTimeMillis()+":T2 start! notify one thread");
                object.notify();
                System.out.println(System.currentTimeMillis()+":T2 end!");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                }
            }
        }
    }

    public static void main(String[] args) {
        Thread1 thread1 = new Thread1();
        Thread2 thread2 = new Thread2();
        thread1.start();
        thread2.start();
    }
}

2.5挂起(suspend)和继续执行(resume)

不推荐使用这两个方法。

2.6等待线程结束(join)和谦让(yield)

public class Client {
    public volatile static int i = 0;

    public static class AddThread extends Thread {
        @Override
        public void run() {
            for (i = 0; i < 10000000; i++);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        AddThread addThread = new AddThread();
        addThread.start();
        addThread.join();
        System.out.println(i);
    }
}

注释join()方法后,i返回为0。

yield()会使当前线程让出cpu,重新参与cpu资源的争夺。

2.7volatile关键字

用volatile申明一个变量后,这个变量被修改后会通知其他的线程。

2.8synchronized关键字

实现线程间的同步,对同步的代码加锁,使得每一次只能有一个线程进入同步块,从而保证线程间的安全性。

2.9并发下的ArrayList

public class Client {
    static ArrayList<Integer> arrayList = new ArrayList<Integer>(10);

    public static class AddThread implements Runnable{
        @Override
        public void run(){
            for (int i = 0; i < 1000000; i++) {
                arrayList.add(i);
            }
        }
    }

    public static void main(String[] args) throws InterruptedException{
        Thread thread1 = new Thread(new AddThread());
        Thread thread2 = new Thread(new AddThread());
        thread1.start();
        thread2.start();
        thread1.join();
        thread2.join();
        System.out.println(arrayList.size());
    }
}

给程序运行会有三种结果

1)程序越界:


2)多线程冲突,导致结果变动


3)极少数情况会出现正确结果

改进方法:用Vector代替ArrayList

static Vector<Integer> arrayList = new Vector<Integer>(10);

2.10并发下的hashmap

同ArrayList问题,所以建议并发下用ConcurrentHashMap代替HashMap

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值