java记录-多线程与锁

JAVA的多线程

Thread线程类,实现了Runable接口
JAVA是抢占式调度,就是优先级高的先获取CPU资源,但并不意味它每一时刻都最快

创建新的线程的方法:

1、创建Thread子类并重写run方法

public class MyThread extends Thread{
	@Override
	public void run(){
		for(int i=0; i<100; ++i){
			System.out.println(String.valueOf(i))
		}
	}//run方法封装线程的动作,直接调用它并不会启动线程,相当于普通方法调用
	MyThread(){
		super();
	}
	MyThread(String name){
		super(name);
	}
}
MyThread my1 = new MyThread();
MyThread my2 = new MyThread();
MyThread my3 = new MyThread("线程3");

my1.setName("线程1");
my2.setName("线程2");

System.out.println(my1.getName()); //如果未指定名称,默认为 Thread-0、Thread-1
System.out.println(my2.getName());
System.out.println(my3.getName());
//start方法才是启动线程的方法
my1.start();
my2.start();
my3.start();

获取目前正在执行的线程对象的引用(每次都不是同一个线程,因为不知道现在是哪个线程获得CPU资源在执行)

Thread th = Thread.currentThread();

获取与设置线程优先级(默认为5,越大优先级越高0~10)

my1.getPriority();
my1.setPriority(10);

使当前在运行的线程暂停执行

Thread.sleep(1000);

阻塞其他操作,等待线程死亡再继续

my1.join();

设置为守护线程(全为守护线程JVM直接终止,因为没有主线程了)

my1.setDaemon(true);

2、实现Runnable接口,重写run方法,在创建Thread时将对象作为参数传入并启动

这种方式可以让工作的类继承它自己的父类,而不是只继承一个Thread
其实Thread也是Runnable的实现类

public class MyWork implements Runnable{
	@Override
	public void run(){
		for(int i=0; i<100; ++i)
			System.out.println(Thread.currentThread().getName()+String.valueOf(i));
	}
}

Thread th1 = new Thread(new MyWork());
Thread th2 = new Thread(new MyWork(), "线程2");
th1.setName("线程1");

th1.start();
th2.start();

同步锁

不懂这是啥的先学操作系统原理的同步异步章节
用同步代码块实现锁,里面是操作共享数据的语句

同步锁会降低单个线程的运行效率,但是保证了数据安全

synchronized(任意对象),这个任意对象是被当成一个锁用,但是必须保证所有线程能接触到的作为锁的对象是同一个!
下面是三个售票窗口并发买票的例子,如果不锁,会出现三个窗口同时卖同一张票的情况,这个叫幻象读

public class Main {
    static long count = 0;
    public static void main(String[] args){
        Thread seller1 = new Thread(new ticketSeller(), "一号售票窗口");
        Thread seller2 = new Thread(new ticketSeller(), "二号售票窗口");
        Thread seller3 = new Thread(new ticketSeller(), "三号售票窗口");
        seller1.start();
        seller2.start();
        seller3.start();
    }
}
class ticketSeller implements Runnable{
    static private int ticketNum = 100;//100张票
    static Object lock = new Object();//自定义的锁

    @Override
    public void run() {
        while(true){
            synchronized (lock) {//使用同步代码块锁住操作共享对象的代码
                if (ticketNum > 0) {
                    try {
                        Thread.sleep((new Random()).nextInt(1000));
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    System.out.println(Thread.currentThread().getName() + "卖出1张票,余票" + String.valueOf(--ticketNum) + "张");
                } else {
                    System.out.println("票卖完了,请回吧");
                    break;
                }
            }
        }
    }
}

也可以直接对方法加锁,用这个方法都是加锁的。
同步方法的锁是this对象,只使用一个对象的同步方法就是唯一的

synchronized void sellTicket(){
	if (ticketNum > 0) {
                    try {
                        Thread.sleep((new Random()).nextInt(1000));
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    System.out.println(Thread.currentThread().getName() + "卖出1张票,余票" + String.valueOf(--ticketNum) + "张");
                } else {
                    System.out.println("票卖完了,请回吧");
                    break;
                }
}

也可以对静态方法加锁
同步静态方法的锁是字节码文件对象(ticketSeller.class),唯一

static synchronized void sellTicket(){
	if (ticketNum > 0) {
                    try {
                        Thread.sleep((new Random()).nextInt(1000));
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    System.out.println(Thread.currentThread().getName() + "卖出1张票,余票" + String.valueOf(--ticketNum) + "张");
                } else {
                    System.out.println("票卖完了,请回吧");
                    break;
                }
}

线程安全类

StringBuffer、vector(类似ArrayList)、Hashtable(类似HashMap)
此外,Collections类给出了方法返回线程安全的类实现

Collections.synchronizedList(List<T>);
Collections.synchronizedSet(Set<T>);
Collections.synchronizedMap(Map<T>);
等等

Lock锁

更加清晰,你能知道锁的位置和何时释放
其实现类为ReentrantLock

Lock lock = new ReetrantLock();
lock.lock();//阻塞其他进程
lock.unlock();//释放资源

生产者消费者模式

Object类有三个方法,wait()、notify()和notifyAll()用于实现
wait()直接阻塞,等待唤醒
notifyAll()是唤醒其他在等的线程
配合synchronized(A)用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值