java-多线程线程锁

多线程实现

重写Thread类的run()方法

代码编写上非常简单,但是相对来能进行的操作就收到了限制。

public class learning extends Thread{
    // 传参可以在构造函数里面将一些参数传入进来
    static int output = 1;
    @Override
    public void run(){
        whilt(true){
            output++;
            System.out.println(output);
        }
    }
}

public static void main(String[] args) throws InterruptedException {
    learning test1 = new learning();
    learning test2 = new learning();
    test1.start();
    test2.start();
    t1.join();
}

实现Runnable接口,重写run方法

如果想要实现更加多的操作推荐使用这种方法,因为可以利用下面的线程实现共享参数的互斥操作

public class learning implements Runnable {
    @Override
    public void run() {
        System.out.println(Thread.currentThread());
    }
}
public static void main(String[] args) throws InterruptedException {
    Thread t1 = new Thread(new ThreadRunnable());
    Thread t2 = new Thread(new ThreadRunnable());
    t1.start();
    t2.start();
    
    t1.join();
}

实现Callable接口(相比于前面两种能够具有返回值)

public class learning implements Callable<Integer> {
    static int output = 1;
    
    @Override
    public Integer call() throws Exception {
        System.out.println(Thread.currentThread());
        return 11;
    }
}

public static void main(String[] args) throws Exception {
    FutureTask<String> t1 = new FutureTask<>(new learning());
    FutureTask<String> t2 = new FutureTask<>(new learning());
    Thread tt1 = new Thread(t1);	//放入需要执行的函数,调用的是learning中的call函数
    Thread tt2 = new Thread(t2);

    tt1.start();	//开始执行线程
    tt2.start();
    
    System.out.println(t2.get());	//这个不能放在start前面,因为在线程开始前,并不会有返回值,会出现持续等待的问题,get是阻塞的

    tt1.join();
	tt2.join();
}

通过线程池创建线程

这部分内容有点多,后续加

线程锁

Synchronized

给共享资源上锁,不需要人为进行acquirerelease,只需要将需要同步的代码块、类放到Synchronized中就可以了,对于不同线程访问同一变量的时候Synchronized能够自动进行上锁、解锁操作。从其他文档的反应来看锁的使用频率是非常高的

用法:

public static void main(String[] args) throws Exception {
    learning ln = new learning();
    Thread t1 = new Thread(ln);
    Thread t2 = new Thread(ln);
    t1.start();
    t2.start();
    t2.join();
}

public class learning implements Runnable {
    static int output = 1;
    @Override
    public void run() {
        synchronized (this){	// 这里参数表示的时候锁的目标,this表示这个实例对象
            for (int i = 0; i < 5; i++) {
                try {
                    System.out.println(Thread.currentThread().getName() + ":" + (output++));
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

ReentrantLock

Synchronized可以被线程多次重复获取操作,也就是说,如果某个线程对Lock已经进行了上锁操作,那么后续如果在这个线程里面也又进行上锁,那么这个操作就会被允许执行。更形象来说就好像是锁已经在自己这边了,自然就可以继续执行后续的操作了。

在性能上,高并发量情况下ReetrantLock具备更高的执行效率。

在创建ReentrantLock的时候可以选择是否是公平锁,默认为非公平锁,效率更高。

​ 公平锁:谁先提出锁的请求谁就会获得这个锁,也就是说两个线程可以整整意义上的交替获得锁

​ 非公平锁:随机就近原则,在比较长的时间中,锁

public static void main(String[] args) throws Exception {
    learning ln = new learning();
    learning ln2 = new learning();
    Thread t1 = new Thread(ln);
    Thread t2 = new Thread(ln2);
    t1.start();
    t2.start();
    t2.join();
}

public class learning implements Runnable {
    static int output = 1;
    static Lock lock = new ReentrantLock();
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            try {
                lock.lock();
                System.out.println(Thread.currentThread().getName() + ":" + (output++));
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    }
}

Semaphore

互斥锁,和PV操作一样,可以设置锁的数量,同一线程进行两次acquire()上锁就会消耗掉两个锁,通过release()释放

public static void main(String[] args) throws Exception {
    learning ln = new learning();
    learning ln2 = new learning();
    Thread t1 = new Thread(ln);
    Thread t2 = new Thread(ln2);
    t1.start();
    t2.start();
    t2.join();
}

public class learning implements Runnable {
    static int output = 1;
    static Semaphore se = new Semaphore(1);
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            try {
                se.acquire();
                System.out.println(Thread.currentThread().getName() + ":" + (output++));
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                se.release();
            }
        }
    }
}

AtomicInteger

因为i++++i等操作都不具备原子性,在多线程进行操作的时候这样的操作行为会存在比较多的问题,所以通过AtomicInteger对单个变量进行操作。但是问题也在于只能同步一个值
} finally {
se.release();
}
}
}
}


## AtomicInteger

因为`i++`、`++i`等操作都不具备原子性,在多线程进行操作的时候这样的操作行为会存在比较多的问题,所以通过AtomicInteger对单个变量进行操作。但是问题也在于只能同步一个值
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值