public class ThreadDemo {
public static void main(String[] args) {
MyThread myThread = new MyThread();
/*开启线程*/
myThread.start();
}
}
class MyThread extends Thread{
@Override
public void run() {
// 写入自己的功能代码
}
}
实现Runnable接口
public class RunnableDemo {
public static void main(String[] args) {
/*通过实现Runnable接口开启多线程*/
MyRunnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable);
thread.start();
/*通过匿名内部类实现*/
new Thread(()-> {
// 写入自己的功能代码
}).start();
new Thread(()-> System.out.println("线程4")).start();
new Thread(()-> System.out.println("线程5")).start();
}
}
class MyRunnable implements Runnable{
@Override
public void run() {
// 写自己的功能代码
}
}
线程常用方法详解Thread.currentThread()
获取当前正在执行此代码的线程信息
public class MyThread {
public static void main(String[] args) {
/**
* ()->{
* // 获取当前线程信息
* Thread thread = Thread.currentThread();
* System.out.println(thread.toString());
*}
* 此处相当于传了一个实现了Runnable接口类的对象
* */
new Thread(()->{
Thread thread = Thread.currentThread();
System.out.println(thread.toString());
}).start();
}
}
Thread.currentThread().isAlive()
判断线程是否处于活动状态
public class MyThread {
public static void main(String[] args) {
new Thread(()->{
System.out.println(Thread.currentThread().isAlive());
}).start();
}
}
Thread.sleep(5000);
使当前线程进行休眠
public class MyThread {
/*HelloWorld需要等待5s才能被打印*/
public static void main(String[] args) {
new Thread(()->{
try {
/*线程休眠*/
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("HelloWorld");
}).start();
}
}
二、实现锁的几种方式
synchronized
synchronized锁定的是对象,而不是代码块,synchronized是可以重入锁,当程序出现异常时会释放锁 public class MyThread {
private static Object object = new Object();
public static void main(String[] args) {
/*此处锁的是object对象*/
synchronized (object){
// 功能代码
}
}
/*此处锁定的是当前对象*/
public synchronized void m(){ }
/*在没有new MyThread类对象时使用m1()方法,锁的是MyThread.class 对象*/
public static synchronized void m1(){ }
/*可重人锁,当线程获取到了执行demo1方法的对象锁,当执行到demo2()时也能获取到对象锁*/
public synchronized void demo1(){
// 功能代码
demo2();
}
public synchronized void demo2(){ }
}
synchronized底层原理(升级锁)
第一个线程进入的时候是偏向锁,所谓偏向锁就是锁对象会记录获取了锁对象的当前线程的id,如果锁没有释放锁,这个时候有另一个线程需要进入,就会用线程id对比一下是不是当前线程如果不是则获取不到锁。 当等待的线程变多就会升级为自旋锁(在用户态进行,在CPU中进行自旋) 进一步升级为重量级锁–OS锁(在内核态进行,不占用CPU) 拓展 线程少,占用锁时间短采用自旋锁,线程多占用锁时间长用系统锁 三、volatile 防止指令重排序 public class Singleton {
/*
* 说明:
* Object o = new Object();
* 此条语句不是原子性操作,并且是分三步进行的
* 1、申请地址空间
* 2、初始化
* 3、将地址赋值给变量o
* 由于JVM存在指令重排机制一次1,2,3不一定会按顺序执行,如果在高并发情况下可能会有线程拿到还未进行初始化的对象
* */
private volatile Singleton instance = null;
private Singleton(){ }
public Singleton getInstance(){
if(instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
return instance;
}
}
保证被修饰变量线程间的可见性,底层是通过CPU的缓存一致性协议(MESI)完成的
public class MyThread extends Thread {
/*此处不加关键字volatile线程thread1将一直在处在wile循环中,因为对主线程修改的flag不可见*/
private static volatile boolean flag = false;
public void run() {
while (!flag);
}
public static void main(String[] args) throws Exception {
Thread thread1 = new MyThread();
thread1.start();
Thread.sleep(2000);
flag = true;
}
}
码农JJ
原创文章 8获赞 5访问量 888
关注
私信
展开阅读全文