创建线程
线程开启不一定立即执行,由cpu调用 执行
方法1:继承Thread类,重写run方法,用start开启线程
package Thread.ThreadTest1;
public class Main {
public static void main(String[] args) {
Test1 test1 = new Test1();
test1.start();
for (int i = 0; i < 200; i++) {
System.out.println("Main"+i);
}
}
}
class Test1 extends Thread{
@Override
public void run() {
for (int i = 0; i < 200; i++) {
System.out.println("线程"+i);
}
}
}
方法:实现runnable接口,重写run方法
package Thread.ThreadTest2;
public class Main {
public static void main(String[] args) {
Thread thread = new Thread(new RunnableTest());
thread.start();
for (int i = 0; i < 200; i++) {
System.out.println("Main"+i);
}
}
}
class RunnableTest implements Runnable{
@Override
public void run() {
for (int i = 0; i < 200; i++) {
System.out.println("Runnable "+ i);
}
}
}
一个对象被多个线程同时使用
package Thread.ThreadTest3;
public class Main {
public static void main(String[] args) {
ThreadTest thread = new ThreadTest();
new Thread( thread, "小明").start();
new Thread( thread, "老师").start();
new Thread( thread, "黄牛").start();
}
}
class ThreadTest implements Runnable{
private int ticket = 10;
@Override
public void run() {
while (true){
if(ticket <=0){
break;
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"拿到第"+ticket--+"张票");
}
}
}
并发问题
龟兔赛跑
package Thread.ThreadTest4;
public class Main {
public static void main(String[] args) {
Test test = new Test();
new Thread(test, "兔子").start();
new Thread(test, "乌龟").start();
}
}
class Test implements Runnable {
private String Winner;
@Override
public void run() {
for (int i = 1; i <= 100; i++) {
boolean flag = gameOver(i);
if (Thread.currentThread().getName().equals("兔子") && i % 10 == 0) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (flag) {
break;
}
System.out.println(Thread.currentThread().getName() + "跑了" + i + "步");
}
}
//判断是否完成比赛
private boolean gameOver(int step) {
if (Winner != null) {
return true;
}
{
if (step == 100) {
Winner = Thread.currentThread().getName();
System.out.println("Winner is" + Winner);
return true;
}
}
return false;
}
}
静态代理模式
- 真实对象和代理对象都要实现一个接口
- 代理对象代理真实角色
好处
- 代理对象可以做很多真实对象做不了的事
- 真实对象只需要做自己做的事
package Thread.TreadTest5;
public class Main {
public static void main(String[] args) {
Mother mother = new Mother(new Son());
mother.eat();
}
}
interface Eat {
void eat();
}
class Son implements Eat {
@Override
public void eat() {
System.out.println("开始吃饭");
}
}
class Mother implements Eat{
private Eat target;
public Mother(Eat target) {
this.target = target;
}
@Override
public void eat() {
before();
this.target.eat();
after();
}
private void after() {
System.out.println("老妈开始做饭");
}
private void before() {
System.out.println("老妈开始洗碗");
}
}
lambda表达式
- lambda表达式只有在一行代码的时候才能简化为一行,如果有多行,需用代码块包裹
- 前提是这个接口为函数式接口
- 这个参数也可以去掉参数类型,要去掉就都去掉
package Thread.LambdaTest;
public class Main {
/* //静态内部类
static class Son implements Eat{
@Override
public void eat(int a,int b) {
System.out.println("I like Eat"+a);
System.out.println("I like Eat"+b);
}
}
*/
public static void main(String[] args) {
//lambda表达式
Eat eat1 = (int a, int b,int c) -> {
System.out.println("I like Eat" + a);
System.out.println("I like Eat" + b);
System.out.println("I like Eat" + c);
};
eat1.eat(10,20,30);
}
}
interface Eat {
void eat(int a, int b,int c);
}
线程使用
线程停止
package Thread.StopTest;
public class Main {
public static void main(String[] args) {
Test test = new Test();
new Thread(test).start();
for (int i = 0; i < 1000; i++) {
System.out.println("Main"+i);
if (i==900){
test.stop();
System.out.println("线程该停止了");
}
}
}
}
class Test implements Runnable{
boolean flag = true;
@Override
public void run() {
int i = 0;
while (flag){
System.out.println("Thread" + i);
i++;
}
}
void stop(){
this.flag = false;
}
}
线程休眠
package Thread.SleepTest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.SimpleTimeZone;
//模拟倒计时
public class Main {
public static void main(String[] args) {
try {
test();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
static void test() throws InterruptedException {
Date date = new Date(System.currentTimeMillis());
while (true){
Thread.sleep(1000);
System.out.println(new SimpleDateFormat("HH,mm,ss").format(date));
date = new Date(System.currentTimeMillis());
}
}
}
线程礼让
package Thread.YieldTest;
public class Main {
public static void main(String[] args) {
new Thread(new MyYield(),"a").start();
new Thread(new MyYield(),"b").start();
}
}
class MyYield implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"开始执行");
Thread.yield();
System.out.println(Thread.currentThread().getName()+"停止执行");
}
}
线程强制执行
package Thread.JoinTest;
public class Main {
public static void main(String[] args) throws InterruptedException {
//启动自定义线程
test test = new test();
Thread thread = new Thread(test);
thread.start();
//启动主线程
for (int i = 0; i < 500; i++) {
if (i == 200) {
thread.join();
}
System.out.println("Main线程" + i);
}
}
}
class test implements Runnable {
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println("vip来了" + i);
}
}
}
线程优先使用
package Thread.SetPriorityTest;
public class Main {
public static void main(String[] args) {
//最先往往是main函数再运行
Test test = new Test();
Thread t1 = new Thread(test,"线程1");
Thread t2 = new Thread(test,"线程2");
Thread t3 = new Thread(test,"线程3");
Thread t4 = new Thread(test,"线程4");
System.out.println(Thread.currentThread().getName() + "在运行" + Thread.currentThread().getPriority());
t1.start();
t2.setPriority(10);
t2.start();
t3.setPriority(1);
t3.start();
t4.setPriority(5);
t4.start();
}
}
class Test implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "在运行" + Thread.currentThread().getPriority());
}
}
守护线程
- 线程分为用户线程和守护线程
- 虚拟机必须确保用户线程执行完毕
- 虚拟机不用等待守护线程执行完毕
package Thread.SetPriorityTest.ProtectThreadTest;
public class Main {
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("这是你开心生活的第"+i+"天");
}
System.out.println("goodbye world!");
}
}
锁
不安全的线程
- 不安全的买票
- 线程不安全,有负数
package Thread.SetPriorityTest.SynchorizedTest;
public class UnSafeTest {
public static void main(String[] args) {
BuyTicket buyTicket = new BuyTicket();
new Thread(buyTicket,"学生").start();
new Thread(buyTicket,"老师").start();
new Thread(buyTicket,"黄牛").start();
}
}
class BuyTicket implements Runnable{
private int TicketNum = 10;
boolean flag = true;
@Override
public void run() {
while (flag){
try {
buy();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
void buy() throws InterruptedException {
if(TicketNum <=0){
flag = false;
return;
}
Thread.sleep(5);
System.out.println(Thread.currentThread().get+"买到"+TicketNum--);
}
}
UnsafeList
package Thread.SynchorizedTest.UnSafeList;
import java.util.ArrayList;
public class Main {
public static void main(String[] args) throws InterruptedException {
ArrayList<Object> list = new ArrayList<>();
for (int i = 0; i < 10000; i++) {
new Thread(()->{list.add(Thread.currentThread().getName());}).start();
}
Thread.sleep(300);
System.out.println(list);
}
}
Synchronize锁
同步方法:解决线程安全,说明给方法加锁,锁对象是方法的对象
悲观锁
package Thread.SynchorizedTest.UnSafeBuyTicket;
public class Main {
public static void main(String[] args) {
BuyTicket buyTicket = new BuyTicket();
new Thread(buyTicket, "老师").start();
new Thread(buyTicket, "黄牛").start();
new Thread(buyTicket, "学生").start();
}
}
class BuyTicket implements Runnable {
private int TicketNum = 100;
boolean flag = true;
@Override
public void run() {
while (flag) {
try {
buy();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
synchronized void buy() throws InterruptedException {
if (TicketNum <= 0) {
flag = false;
return;
}
Thread.sleep(500);
System.out.println(Thread.currentThread().getName() + "买到" + TicketNum--);
}
}
同步代码块
package Thread.SynchorizedTest.UnSafeBuyTicket;
public class Main {
public static void main(String[] args) {
BuyTicket buyTicket = new BuyTicket();
new Thread(buyTicket, "老师").start();
new Thread(buyTicket, "黄牛").start();
new Thread(buyTicket, "学生").start();
}
}
class BuyTicket implements Runnable {
private int TicketNum = 100;
boolean flag = true;
@Override
public void run() {
while (flag) {
try {
buy();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
void buy() throws InterruptedException {
if (TicketNum<=1) {
flag = false;
return;
}
Thread.sleep(30);
synchronized (this){
//可能出现安全的代码
System.out.println(Thread.currentThread().getName() + "买到" + TicketNum);
TicketNum = TicketNum-1;
}
}
}
死锁
产生死锁的四个必要条件:
-
互斥条件:一个资源每次只能被一个进程使用
-
请求与保持条件:一个进程因请求资源二阻塞时,已获得的资源保持不放
-
不剥夺条件:进程已获得资源,在未使用完之前,不能强行剥夺
-
循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系
package Thread.SynchorizedTest.DeadLock;
public class Main {
public static void main(String[] args) {
new Eat(1,"小明").start();
new Eat(0,"小红").start();
}
}
class Chopsticks{}
class Dish{}
class Eat extends Thread{
static Chopsticks chopsticks = new Chopsticks();
static Dish dish = new Dish();
int choice;
String name;
Eat(int choice,String name){
this.choice = choice;
this.name = name;
}
@Override
public void run() {
try {
eat();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
void eat() throws InterruptedException {
if (choice == 0){
synchronized (dish){
System.out.println(name+"拿到了盘子");
Thread.sleep(2000);
}
synchronized (chopsticks){
System.out.println(name+"拿到筷子");
}
}else {
synchronized (chopsticks){
System.out.println(name+"拿到了筷子");
Thread.sleep(1000);
}
synchronized (dish){
System.out.println(name+"拿到盘子");
}
}
}
}
线程池
package Thread.ExecutorSeriveTest;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {
public static void main(String[] args) {
ExecutorService service = Executors.newFixedThreadPool(10);
service.execute(new test());
service.execute(new test());
service.execute(new test());
service.execute(new test());
}
}
class test implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}