Java笔记3(线程)
只是一些自己认为重点和易错点的笔记
线程相关笔记
1、进程与线程
- 进程由静态的程序运行是产生的;
- 进程相当于是一个大的模块,里边包含了各个线程来具体实现东西;
- 至少有一个线程,否则进程没有意义;
- 线程开启不一定立即执行,是由CPU调度的。
2、创建线程的方法
a、通过继承Thread类来创建
- 创建类来继承Thread类(假设类为test);
- 重写run()方法;
- 创建test类的对象,用这个对象调用start()方法来启动线程。
b、通过实现Runnable接口来创建
-
创建类来继承Thread类(假设类为test1);
-
重写run()方法;
-
创建test1类的对象p,再创建Thread对象,将p放到Thread对象中,在调用start方法。
即用线程的对象类开启线程(要用魔法打败魔法*_*)
//第二种方法的第三步 new Thread(p).start();两种方法的前两步都是一样的,只有第三步有些差别
3、并发
- 一个资源可以被多个线程所使用;
- 但是会有问题,例如:多人抢票,会出现多个人抢到同一张票的情况;
4、静态代理模式
//结婚代理
//真实对象和代理对象要实现同一个接口
//真实对象专注做自己的事
public class StaticProxy {
public static void main(String[] args) {
MarryCompany mc = new MarryCompany(new You());
mc.marry();
}
}
//结婚接口
interface Marry{
void marry();
}
//你
class You implements Marry{
@Override
public void marry() {
System.out.println("Today marry.");
}
}
//婚庆公司
class MarryCompany implements Marry{
private Marry target;
public MarryCompany(Marry tar){
this.target=tar;
}
@Override
public void marry() {
this.befor();
this.target.marry();
this.after();
}
private void after() {
System.out.println("后");
}
private void befor() {
System.out.println("前");
}
-
使用lamda表达式来简化掉真实对象
/结婚代理 public class StaticProxy { public static void main(String[] args) { // MarryCompany mc = new MarryCompany(new You()); // mc.marry(); //使用lamda表达式可以简化掉真实对象部分的实现 new MarryCompany(()-> System.out.println("today.....")).marry(); } } //结婚接口 interface Marry{ void marry(); } //你 //class You implements Marry{ // // @Override // public void marry() { // System.out.println("Today marry."); // } //} //婚庆公司 class MarryCompany implements Marry{ private Marry target; public MarryCompany(Marry tar){ this.target=tar; } @Override public void marry() { this.befor(); this.target.marry(); this.after(); } private void after() { System.out.println("后"); } private void befor() { System.out.println("前"); } }
5、线程停止(stop)
- 线程五大状态
- 创建
- 就绪
- 运行
- 阻塞
- 死亡
public class TestStop implements Runnable {
//设置标志位
boolean flag = true;
@Override
public void run() {
int i = 0;
while (flag){
System.out.println("线程运行中"+ i++);
}
}
//改变标志位状态
public void stop(){
this.flag = false;
}
public static void main(String[] args) {
TestStop tt = new TestStop();
//开启线程
new Thread(tt).start();
//运行主线程
for (int i = 0; i < 1000; i++) {
System.out.println(i);
if(i == 990){
tt.stop();
System.out.println("线程停止了");
}
}
}
}
6、线程休眠(sleep)
- 可实现倒计时
- 模拟网络延时
- 每个对象都有一把锁,sleep不会释放锁。
//当前时间的显示
public static void main(String[] args) {
Date date = new Date(System.currentTimeMillis());
while (true){
try {
System.out.println(new SimpleDateFormat("HH:mm:ss").format(date));
Thread.sleep(1000);
date = new Date(System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
7、线程礼让(yield)
/**
* 测试线程礼让
*/
public class TestYield {
public static void main(String[] args) {
Myyeird my = new Myyeird();
new Thread(my,"a").start();
new Thread(my,"b").start();
}
}
class Myyeird implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "线程开始");
Thread.yield();
System.out.println(Thread.currentThread().getName() + "线程结束");
}
}
//这个没测试成功,不知道什么地方出了问题
8、线程强制执行(join)
-
在达到条件之前CPU随机调度线程
当达到条件后先调用插队的线程。
public class TestJoin implements Runnable {
@Override
public void run() {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < 1000; i++) {
System.out.println("插队的来了" + i);
}
}
public static void main(String[] args) throws InterruptedException {
//启动线程
TestJoin tj = new TestJoin();
Thread thread = new Thread(tj);
thread.start();
//主线程
for (int i = 0; i < 500; i++) {
if(i==200){
thread.join();
}
System.out.println("main" + i);
}
}
}
9、观测线程状态
public class TestState {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(()->{
for (int i = 0; i < 2; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("延迟结束");
});
//监测状态
Thread.State state = thread.getState();
System.out.println(state); //New
//开启线程
thread.start();
state = thread.getState();
System.out.println(state); //run
while (state != Thread.State.TERMINATED){ //主要线程不终止,就一直输出状态
Thread.sleep(100);
state = thread.getState(); //更新线程状态
System.out.println(state);
}
}
}
NEW
RUNNABLE
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
延迟结束
TERMINATED
10、线程优先级
- 优先级高只是被CPU调度的几率高
public class TestPriority {
public static void main(String[] args) {
//主线程默认优先级
System.out.println(Thread.currentThread().getName() + "---->"+Thread.currentThread().getPriority());
MyPriority mp = new MyPriority();
Thread t1 = new Thread(mp);
Thread t2 = new Thread(mp);
Thread t3 = new Thread(mp);
Thread t4 = new Thread(mp);
t1.setPriority(Thread.MIN_PRIORITY); //优先级最小为1
t1.start();
t2.setPriority(4);
t2.start();
t3.setPriority(8);
t3.start();
t4.setPriority(Thread.MAX_PRIORITY); //优先级最大为10
t4.start();
}
}
class MyPriority implements Runnable{
@Override
public void run() {
//输出线程名称和优先级
System.out.println(Thread.currentThread().getName() + "---->"+ Thread.currentThread().getPriority());
}
}
main---->5
Thread-0---->1
Thread-1---->4
Thread-3---->10
Thread-2---->8
11、守护线程
-
线程分为用户线程和守护线程
-
虚拟机必须确保用户线程执行完毕;
不用等待守护线程执行完毕。
public class TestDeamon {
public static void main(String[] args) {
God god = new God();
You you = new You();
Thread thread = new Thread(god);
thread.setDaemon(true); //创建的线程默认为用户线程
thread.start();
new Thread(you).start();
}
}
class God implements Runnable{
@Override
public void run() {
while(true){
System.out.println("上帝守护着你");
}
}
}
class You implements Runnable{
@Override
public void run() {
for (int i = 0; i < 36500; i++) {
System.out.println("一直开心地活着");
}
System.out.println("goodbye,world");
}
}
12、同步方法和同步块
-
同步方法:添加synchronized修饰符
同步块:
public static void main(String[] args) { List<String> list = new ArrayList<>(); for (int i = 0; i < 10000; i++) { new Thread(()->{ //锁的对象是需要增删改的 synchronized(list){ list.add(Thread.currentThread().getName()); } }).start(); } try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(list.size()); }
13、Lock锁
public class BuyTicket {
//购票
public static void main(String[] args) {
Buy buy = new Buy();
new Thread(buy).start();
new Thread(buy).start();
new Thread(buy).start();
}
}
class Buy implements Runnable{
//票数
int tackets = 10;
ReentrantLock lock = new ReentrantLock();
@Override
public void run() {
while (true){
try{
lock.lock(); //加锁
if(tackets > 0){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
}
System.out.println("票数为:" + tackets--);
}else {
break;
}
}finally {
lock.unlock(); //解锁
}
}
}
}
非常感谢狂神的教学
有错误的地方欢迎指正,一起交流

浙公网安备 33010602011771号