第十九节——线程与同步代码块和锁

线程的学习

一、线程实现方法一:

  1. 定义一个类MyThread继承Thread类
  2. 在MyThread类中重写run()方法,在run方法中的是线程可以执行的部分,没有在run方法中,线程执行时不运行
  3. 创建MyThread类的对象
  4. 启动线程,start方法,此方法默认调用run方法,不用专门指定run方法
  5. 举例:
//新建一个继承Thread的类
public class Test1 extends Thread{
    
    
    @Override
    public void run() {
    
    
        System.out.println("run方法");
    }
    public void show(){
    
    
        System.out.println("show方法");
    }
}
//使用线程类
Test1 t1 = new Test1();
t1.start();

二、线程实现方法二:

  1. 定义一个类MyRunnable实现Runnable接口
  2. 在MyRunnable类中重写run()方法
  3. 创建MyRunnable类的对象
  4. 创建Thread类的对象,把MyRunnable对象作为构造方法的参数
  5. 启动线程
  6. 举例:
//定义类实现Runnable接口
public class Test1 implements Runnable{
    
    
    @Override
    public void run() {
    
    
        System.out.println("run方法");
    }
}
//使用线程
Test1 t1 = new Test1();
Thread t = new Thread(t1,"线程1");
t.start();

三、设置和获取线程名称

  1. void setName(String name) 将此线程的名称更改为等于参数name
  2. String getName() 返回此线程的名称
  3. Thread currentThread() 返回对当前正在执行的线程对象的引用
  4. 举例:
//定义一个线程类
public class Test2 extends Thread{
    
    
    @Override
    public void run() {
    
    
        System.out.println("线程2");
    }
}
//使用方法
Test2 test2 = new Test2();
System.out.println(test2.getName());
test2.setName("qwe");
System.out.println(test2.getName());
String name1=Thread.currentThread().getName();
System.out.println(name1);

四、线程优先级

  1. final int getPriority() :返回此线程的优先级
  2. final void setPriority(int newPriority):更改此线程的优先级 线程默认优先级是5;线程优先级的范围是:1-10
  3. 举例
Test2 test2 = new Test2();
System.out.println(test2.getPriority());
test2.setPriority(1);

五、线程控制

  1. static void sleep(long millis) :使当前正在执行的线程停留(暂停执行)指定的毫秒数,用法:Thread.sleep()
  2. void join() :等待这个线程死亡,让线程1嗲用了join方法,其他线程必须等待线程1结束才能执行
  3. void setDaemon(boolean on):true=将此线程标记为守护线程,当运行的线程都是守护线程时,Java虚拟机将退出
  4. 举例:
//在线程类中使用sleep
public class Test2 extends Thread{
    
    
    @Override
    public void run() {
    
    
        for (int i=0;i<1000;i++) {
    
    
            System.out.println("线程2");
            try {
    
    
                Thread.sleep(50000);//每循环一次暂停一下
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
        }
    }
}
//类使用时暂定
Test2 test2 = new Test2();
test2.start();
Thread.sleep(50000); //当类的run方法执行完后暂停
test2.join();
test2.setDaemon(true); //在main线程中设置test2为main的守护线程,main线程结束,test2就立刻结束

同步代码块的学习

一、同步代码块的使用场景

  1. 多线程环境
  2. 多线程有共享数据
  3. 有多条语句操作共享数据
  4. 举例:
//定义一个线程类,不在run方法中的资源即为共享数据
public class Test2 extends Thread{
    
    
    String s = "共享数据";
    @Override
    public void run() {
    
    
        System.out.println(s);
    }
}
//创建多个对象,构建多线程环境,且使用共享数据
Test2 t1 = new Test2();
Test2 t2 = new Test2();
t1.start();
t2.start();

二、使用同步代码块解决共享资源互斥

  1. 格式:synchronized(任意对象) {多条语句操作共享数据的代码}
  2. 举例:
public class Test2 extends Thread{
    
    
    String s = "共享数据";
    private final Object obj = new Object();  //创建一把锁
    @Override
    public void run() {
    
    
        synchronized (obj) {
    
      //每个线程执行这个代码使用共享资源时都是互斥的
            System.out.println(s);
        }
    }
}

三、使用锁来实现互斥

  1. ReentrantLock() :创建一个ReentrantLock的实例
  2. void lock() :获得锁
  3. void unlock(): 释放锁
  4. 举例:
public class Test2 extends Thread{
    
    
    String s = "共享数据";
    private final Lock lock = new ReentrantLock(); //创建锁对象
    @Override
    public void run() {
    
    
        lock.lock();  //上锁获取共享资源
        System.out.println(s);  //使用资源
        lock.unlock();  //解锁,释放共享资源
    }
}

猜你喜欢

转载自blog.csdn.net/qq_37589805/article/details/119670957
今日推荐