目录
线程的概述
一个线程一个栈
单核cpu能做到真正的多线程并发吗
创建线程的主要方法一之继承Thread重要
extend Thread线程的执行流程.
创建线程的主要方法二之实现Runnable重要
第二种的方法比较常用,面向接口编程
创建线程的主要方法三之实现Callable重要
线程生命周期
Thread中的sleep![](https://i-blog.csdnimg.cn/blog_migrate/a9a8367a196c2bcd49691c373f291823.png)
Thread中sleep中面试题
这里会导致main线程睡眠。t线程不会睡眠
多线程的重要认知
多线程并发银行示例图
JAVA中三大变量多线程并发安全性
实例变量和静态变量也是成员变量
回顾StringBuffer和StringBuilder
synchronized面试题
一、
package com.atguigu.Exam01;
/**
* @author shkstart
* @create 2023-01-15 13:46
*/
public class examTest {
public static void main(String[] args) {
Person person = new Person();
MyThred m1 = new MyThred(person);
MyThred m2 = new MyThred(person);
m1.setName("m1");
m2.setName("m2");
m1.start();
m2.start();
}
}
class MyThred extends Thread {
private Person person;
public MyThred(Person person) {
this.person = person;
}
@Override
public void run() {
if (Thread.currentThread().getName().equals("m1")){
person.dosome();
}
if (Thread.currentThread().getName().equals("m2")){
person.doother();
}
}
}
class Person {
// 1、如果只有一个方法上面加了synchronized关键字,n那么不会线程同步,因为另外一个方法上没锁。
// 所以两个线程没有共享一个锁,就不会存在线程同步
/* 输出结果 dosom Start
doother Start
doother End
dosom End
*/
public synchronized void dosome() {
System.out.println("dosom Start");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("dosom End");
}
public void doother() {
System.out.println("doother Start");
System.out.println("doother End");
}
}
二:
package com.atguigu.Exam02;
import com.atguigu.test.Bean.Person;
/**
* @author shkstart
* @create 2023-01-15 14:04
*/
public class ExamTest02 {
public static void main(String[] args) {
Person1 person = new Person1();
MyThread m1 = new MyThread(person);
MyThread m2 = new MyThread(person);
m1.setName("m1");
m2.setName("m2");
m1.start();
m2.start();
}
}
class MyThread extends Thread {
private Person1 person;
public MyThread(Person1 person) {
this.person = person;
}
@Override
public void run() {
if (Thread.currentThread().getName().equals("m1")){
person.doSome();
}
if (Thread.currentThread().getName().equals("m2")){
person.doOther();
}
}
}
class Person1 {
// /* 此时两个方法上面都有synchronized,但是它们是共用一把锁。
// 当一个线程正在占有这把锁,另外一个线程需要等待它释放*/
/*
所以输出的结果如下:
doSome Start
domSom End
doOther Start
doOther End
* */
public synchronized void doSome() {
System.out.println("doSome Start");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("domSom End");
}
public synchronized void doOther() {
System.out.println("doOther Start");
System.out.println("doOther End");
}
}
三:
package com.atguigu.Exam03;
import com.atguigu.test.Bean.Person;
/**
* @author shkstart
* @create 2023-01-15 14:04
*/
public class Exam03Test {
public static void main(String[] args) {
// 创建了两个对象
Person1 person = new Person1();
Person1 person1 = new Person1();
MyThread m1 = new MyThread(person);
MyThread m2 = new MyThread(person1);
m1.setName("m1");
m2.setName("m2");
m1.start();
m2.start();
}
}
class MyThread extends Thread {
private Person1 person;
public MyThread(Person1 person) {
this.person = person;
}
@Override
public void run() {
if (Thread.currentThread().getName().equals("m1")){
person.doSome();
}
if (Thread.currentThread().getName().equals("m2")){
person.doOther();
}
}
}
class Person1 {
// /* 此时两个方法上面都有synchronized,但是上面创建了两个对象
//执行第一个方法,锁被人拿走了,执行第二个方法,锁被别人拿走了。但是它们这两个锁的不一样的
/*
所以输出的结果如下:
doSome Start
doOther Start
doOther End
domSom End
* */
public synchronized void doSome() {
System.out.println("doSome Start");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("domSom End");
}
public synchronized void doOther() {
System.out.println("doOther Start");
System.out.println("doOther End");
}
}
四:
package com.atguigu.Exam03;
import com.atguigu.test.Bean.Person;
/**
* @author shkstart
* @create 2023-01-15 14:04
*/
public class Exam03Test {
public static void main(String[] args) {
// 创建了两个对象
Person1 person = new Person1();
Person1 person1 = new Person1();
MyThread m1 = new MyThread(person);
MyThread m2 = new MyThread(person1);
m1.setName("m1");
m2.setName("m2");
m1.start();
m2.start();
}
}
class MyThread extends Thread {
private Person1 person;
public MyThread(Person1 person) {
this.person = person;
}
@Override
public void run() {
if (Thread.currentThread().getName().equals("m1")){
person.doSome();
}
if (Thread.currentThread().getName().equals("m2")){
person.doOther();
}
}
}
class Person1 {
// /* 此时两个方法上面都有synchronized,上面创建了两个对象。但是这两个方法是静态的,所以这就是类锁
// 这个person1类就只有一把锁
//执行第一个方法,锁被人拿走了,执行第二个方法,锁被别人拿走了。但是它们这两个锁的不一样的
/*
所以输出的结果如下:
doSome Start
domSom End
doOther Start
doOther End
* */
public synchronized static void doSome() {
System.out.println("doSome Start");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("domSom End");
}
public synchronized static void doOther() {
System.out.println("doOther Start");
System.out.println("doOther End");
}
}
以后开发怎么解决线程安全问题
定时器
/*
关于定时器的应用.
作用:每隔一段固定的时间执行一段代码.
*/
import java.text.*;
import java.util.*;
public class TimerTest01
{
public static void main(String[] args) throws Exception{
//1.创建定时器
Timer t = new Timer();
//2.指定定时任务
t.schedule(
new LogTimerTask(),
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS").parse("2012-08-03 17:37:00 000"),
1000*10);
}
}
//指定任务
class LogTimerTask extends TimerTask
{
public void run(){
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS").format(new Date()));
}
}
wait和notify的理解
生产者和消费者模式
死锁
package com.atguigu.deadLock;
/**
* @author shkstart
* @create 2023-01-15 15:13
*/
public class deadLock {
public static void main(String[] args) {
Object o1 = new Object();
Object o2 = new Object();
Mythread m1 = new Mythread(o1,o2);
Mythread m2 = new Mythread(o1,o2);
m1.setName("m1");
m2.setName("m2");
m1.start();
m2.start();
}
}
class Mythread extends Thread {
Object o1;
Object o2;
public Mythread(Object o1, Object o2) {
this.o1 = o1;
this.o2 = o2;
}
@Override
public void run() {
synchronized (o1){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (o2){
}
}
}
}
class Mythread1 extends Thread {
Object o1;
Object o2;
public Mythread1(Object o1, Object o2) {
this.o1 = o1;
this.o2 = o2;
}
@Override
public void run() {
synchronized (o2){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (o1){
}
}
}
}