第十九节——线程与同步代码块和锁
Posted 想学习安全的小白
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第十九节——线程与同步代码块和锁相关的知识,希望对你有一定的参考价值。
线程的学习
一、线程实现方法一:
- 定义一个类MyThread继承Thread类
- 在MyThread类中重写run()方法,在run方法中的是线程可以执行的部分,没有在run方法中,线程执行时不运行
- 创建MyThread类的对象
- 启动线程,start方法,此方法默认调用run方法,不用专门指定run方法
- 举例:
//新建一个继承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();
二、线程实现方法二:
- 定义一个类MyRunnable实现Runnable接口
- 在MyRunnable类中重写run()方法
- 创建MyRunnable类的对象
- 创建Thread类的对象,把MyRunnable对象作为构造方法的参数
- 启动线程
- 举例:
//定义类实现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();
三、设置和获取线程名称
- void setName(String name) 将此线程的名称更改为等于参数name
- String getName() 返回此线程的名称
- Thread currentThread() 返回对当前正在执行的线程对象的引用
- 举例:
//定义一个线程类
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);
四、线程优先级
- final int getPriority() :返回此线程的优先级
- final void setPriority(int newPriority):更改此线程的优先级 线程默认优先级是5;线程优先级的范围是:1-10
- 举例
Test2 test2 = new Test2();
System.out.println(test2.getPriority());
test2.setPriority(1);
五、线程控制
- static void sleep(long millis) :使当前正在执行的线程停留(暂停执行)指定的毫秒数,用法:Thread.sleep()
- void join() :等待这个线程死亡,让线程1嗲用了join方法,其他线程必须等待线程1结束才能执行
- void setDaemon(boolean on):true=将此线程标记为守护线程,当运行的线程都是守护线程时,Java虚拟机将退出
- 举例:
//在线程类中使用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就立刻结束
同步代码块的学习
一、同步代码块的使用场景
- 多线程环境
- 多线程有共享数据
- 有多条语句操作共享数据
- 举例:
//定义一个线程类,不在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();
二、使用同步代码块解决共享资源互斥
- 格式:synchronized(任意对象) {多条语句操作共享数据的代码}
- 举例:
public class Test2 extends Thread{
String s = "共享数据";
private final Object obj = new Object(); //创建一把锁
@Override
public void run() {
synchronized (obj) { //每个线程执行这个代码使用共享资源时都是互斥的
System.out.println(s);
}
}
}
三、使用锁来实现互斥
- ReentrantLock() :创建一个ReentrantLock的实例
- void lock() :获得锁
- void unlock(): 释放锁
- 举例:
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(); //解锁,释放共享资源
}
}
以上是关于第十九节——线程与同步代码块和锁的主要内容,如果未能解决你的问题,请参考以下文章