java 大数据学习笔记(一)并行开发

本文介绍了Java中多线程的基础概念,包括主线程的自动创建、自定义线程的两种方法、同步机制(如synchronized关键字)、并发包(如java.util.concurrent)中的高级同步工具(如Lock、ReadWriteLock、Semaphore、Exchanger)以及如何解决线程间的数据竞争问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第一次写博客 2016.4.18


并发肯定就需要用到java的多线程了,首先得清楚就算没用上多线程就只简单写个hello world,事实上jvm就已经自动创建了一个main thread了:System.out.println(Thread.currentThread().getName());

自己创建线程的两种方法:

一般第一种,传入一个Runnable的借口实现类,在run方法中应该写这个线程的task代码

Thread t = new Thread(new Runnable(){

        @Override
        public void run() {
            // do work;
        }

        });

    t.start();

第二种需要继承Thread,损失了扩展性。

class Test1 extends Thread {

        Test1() {
        }

        @Override
        public void run() {
            // do work;
        }

        public static void main(String[] args) {
            new Test1().start();
        }

    }

多个线程并发地读写同一个资源会产生不可预测的错误,所以我们需要让多个线程安全地访问同一个资源,所以有了同步。synchronized。

public class Test implements Runnable {
    Source source;

    Test(Source source) {
        this.source = source;
    }

    public static void main(String[] args) {

        Source source = new Source();
        System.out.println("hello zxisl");
        System.out.println(Thread.currentThread().getName());

        Thread t = new Thread(new Test(source));



        t.start();

        new Test1(source).start();

    }

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName() + ":" + source.work());
        }

    }
}

    class Test1 extends Thread {
    Source source;

    Test1(Source source) {
        this.source = source;
        }

        @Override
        public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName() + ":" + source.work());

        }
        }

    }

class Source {
    private int i;

    public int work() {
        synchronized (this) {//假如i代表第i张火车票两个线程代表两个售票窗口,如果不同步,同一张火车票可能被卖出两次。
            i++;
            try {
                Thread.sleep(50);//为了让效果明显
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return i;
        }
    }

}

synchronized (this) 对象同步。
synchronized (className.class) 类同步。
具体不写了。
这里有一个疑问 假如一个类中两个方法有同步锁,一个被锁定的时候影响另一个同步方法么?有时间去测试一下。

5.0之后 java.util.concurrent 并发包里还提供了强大的同步锁lock。

public class Testlock {
    static int i;
    static Lock lock = new ReentrantLock();

    public static void main(String[] args) {

        new Thread(new Runnable() {

            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
//                  lock.lock(); //lock与unlock之间的代码等同于synchronized代码快。
                    Testlock.i++;
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + ":" + Testlock.i);
//                  lock.unlock();
                }
            }

        }).start();

        new Thread(new Runnable() {

            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
//                  lock.lock();
                    Testlock.i++;
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + ":" + Testlock.i);
//                  lock.unlock();
                }
            }

        }).start();


    }


}

concurrent包里面的其它:

ReadWriteLock

内置两个Lock,一个是读的Lock,一个是写的Lock。
* 多个线程可同时得到读的Lock,但只有一个线程能得到写的Lock,
* 而且写的Lock被锁定后,任何线程都不能得到Lock。ReadWriteLock提供的方法有:
* readLock(): 返回一个读的lock
* writeLock(): 返回一个写的lock, 此lock是排他的。
* ReadWriteLockTest很适合处理类似文件的读写操作。
* 读的时候可以同时读,但不能写;写的时候既不能同时写也不能读。

CyclicBarrier

允许一组线程互相等待,直到到达某个公共屏障点。

CyclicBarrier(int,Runnable);//当await的数量到达了设定的数量后,首先执行该Runnable对象。
await(); //通知barrier已完成线程
Semaphore

运行规定多个线程并发访问资源。信号量机制, 当每个线程获得资源,信号量-1,当前信号量为0,必须阻塞等待其他线程释放资源。

Exchanger

可以在两个线程之间交换数据,只能是2个线程。当线程A调用Exchange对象的exchange()方法后,他会陷入阻塞状态,直到线程B也调用了exchange()方法,然后以线程安全的方式交换数据,之后线程A和B继续运行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值