一个进程里面可以有多个线程
继承Thread类的使用方法
package 多线程.Thread;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
public class TestThread extends Thread{
//网络图片地址
private String url;
//保存的文件名
private String name;
public TestThread(String url, String name) {
this.url = url;
this.name = name;
}
@Override
public void run() {
WebDownloader wd = new WebDownloader();
wd.downloader(url, name);
System.out.println("文件下载名称:" + name);
}
public static void main(String[] args) {
TestThread t1 = new TestThread("https://img-blog.csdnimg.cn/img_convert/0870ce70301a73980f1a1c790450beb8.png","1.jpg");
t1.start();
System.out.println("下载完成");
}
}
class WebDownloader{
public void downloader(String url, String name){
try {
FileUtils.copyURLToFile(new URL(url), new File(name));
} catch (IOException e) {
e.printStackTrace();
System.out.println(e.toString());
}
}
}
实现Runnable接口
package 多线程.Thread;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
public class TestThread2 extends Thread{
//网络图片地址
private String url;
//保存的文件名
private String name;
public TestThread2(String url, String name) {
this.url = url;
this.name = name;
}
@Override
public void run() {
WebDownloader1 wd = new WebDownloader1();
wd.downloader(url, name);
System.out.println("文件下载名称:" + name);
}
public static void main(String[] args) {
Thread t = new Thread(new TestThread2("https://img-blog.csdnimg.cn/img_convert/0870ce70301a73980f1a1c790450beb8.png","1.jpg"));
t.start();
System.out.println("下载完成");
}
}
class WebDownloader1{
public void downloader(String url, String name){
try {
FileUtils.copyURLToFile(new URL(url), new File(name));
} catch (IOException e) {
e.printStackTrace();
System.out.println(e.toString());
}
}
}
并发问题:多次调用线程 同时对同一个资源进行了调用
龟兔赛跑问题
package 多线程.Race;
public class Race implements Runnable{
private static String Winner;
@Override
public void run() {
for (int i = 0; i <= 100; i++) {
if (Thread.currentThread().getName().equals("兔子") && i%10 == 0){
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
boolean flag = gameOver(i);
if (flag){
break;
}
System.out.println(Thread.currentThread().getName() + "跑了" + i + "步" );
}
}
private boolean gameOver(int steps){
if (Winner != null){
return true;
}else {
if (steps >= 100){
Winner = Thread.currentThread().getName();
System.out.println(Winner + "获胜");
return true;
}
}
return false;
}
public static void main(String[] args) {
Race race = new Race();
new Thread(race , "兔子").start();
new Thread(race , "乌龟").start();
}
}
Lamda表达式
package 多线程.lambda;
public class TestLambda {
public static void main(String[] args) {
like1 l1 = new like1();
l1.lambda();
//局部内部类
class like2 implements ILike{
@Override
public void lambda() {
System.out.println("嘿嘿嘿嘿嘿");
}
}
like2 l2 = new like2();
l2.lambda();
//匿名内部类
ILike l3 = new ILike(){
@Override
public void lambda() {
System.out.println("嗯嗯嗯嗯嗯");
}
};
l3.lambda();
//lambda表达式
ILike l4 = () -> System.out.println("6666666666");
l4.lambda();
}
}
interface ILike{
void lambda();
}
//静态内部类
class like1 implements ILike{
@Override
public void lambda() {
System.out.println("哈哈哈哈哈");
}
}
线程停止函数(最好不要直接调用stop)
package 多线程.Stop;
public class TestStop implements Runnable{
private 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 ts = new TestStop();
new Thread(ts).start();
for (int i = 0; i < 1000000; i++) {
if (i == 900000){
ts.stop();
System.out.println("线程停止");
}
}
}
}
线程礼让
package 多线程.Yield;
public class TestYield {
public static void main(String[] args) {
MyYield m = new MyYield();
new Thread(m , "A").start();
new Thread(m , "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 多线程.Join;
public class TestJoin implements Runnable{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("线程开始执行" + i);
}
}
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(new TestJoin());
t.start();
for (int i = 0; i < 500; i++) {
if (i == 200){
t.join();
}
System.out.println("主线程正在执行" + i);
}
}
}
线程状态
package 多线程.State;
public class TestState {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(() -> {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//线程状态停止
System.out.println("1111111111111111");
});
Thread.State s = t.getState();
//线程状态 开始
System.out.println(s);
t.start();
s = t.getState();
//线程状态 就绪
System.out.println(s);
while (s != Thread.State.TERMINATED){
Thread.sleep(100);
s = t.getState();
//线程状态 运行
//线程最终状态 关闭
System.out.println(s);
}
}
}
线程优先级
package 多线程.Prioritry;
public class TextPriority {
public static void main(String[] args) {
Thread t1 = new Thread(new MyPriority() , "A");
Thread t2 = new Thread(new MyPriority() , "B");
Thread t3 = new Thread(new MyPriority() , "C");
Thread t4 = new Thread(new MyPriority() , "D");
Thread t5 = new Thread(new MyPriority() , "E");
t1.start();
t2.setPriority(Thread.MAX_PRIORITY);
t2.start();
t3.setPriority(Thread.MIN_PRIORITY);
t3.start();
t4.setPriority(Thread.NORM_PRIORITY);
t4.start();
t5.setPriority(6);
t5.start();
}
}
class MyPriority implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + Thread.currentThread().getPriority());
}
}
保护线程
package 多线程.Daemon;
public class TestDaemon {
public static void main(String[] args) {
Thread t = new Thread(new God());
//设置保护线程
t.setDaemon(true);
t.start();
Thread tp = new Thread(new People());
tp.start();
}
}
//定义保护线程
class God implements Runnable{
@Override
public void run() {
while (true){
System.out.println("保护线程运行中");
}
}
}
//定义线程
class People implements Runnable{
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println("我在运行中");
}
System.out.println("我已运行完成");
}
}
线程同步
package 多线程.UnsafeBuyTicket;
public class TestBuyTicket {
public static void main(String[] args) {
BuyTicket bt = new BuyTicket();
Thread t1 = new Thread(bt , "A");
Thread t2 = new Thread(bt , "B");
Thread t3 = new Thread(bt , "C");
Thread t4 = new Thread(bt , "D");
t1.start();
t2.start();
t3.start();
t4.start();
}
}
//买票线程
class BuyTicket implements Runnable{
//票数
private int TicketNum = 15;
//是否卖完
private boolean falg = true;
@Override
public void run() {
while (falg){
buy();
}
}
private synchronized void buy(){
//判断是否卖完
if (TicketNum <= 0){
falg =false;
return;
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "获得第" + TicketNum-- + "张票" );
}
}
package 多线程.JUC;
import java.util.ArrayList;
import java.util.concurrent.CopyOnWriteArrayList;
public class TestJUC {
public static void main(String[] args) {
CopyOnWriteArrayList<String> ci = new CopyOnWriteArrayList<>();
for (int i = 0; i < 10000; i++) {
new Thread(() -> {
ci.add(Thread.currentThread().getName());
}).start();
}
System.out.println(ci.size());
ArrayList a = new ArrayList();
for (int i = 0; i < 10000; i++) {
new Thread(() -> {
synchronized (a){
a.add(Thread.currentThread().getName());
}
}).start();
}
System.out.println(a.size());
}
}
死锁
死锁:多个线程同时持有别人的资源形成的死循环等待
四个必要条件
1.互斥条件:一个资源只能被一个进程使用
2.请求和保持条件:一个进程因请求资源而阻塞时,释放获得的资源
3.不剥夺条件:进程已获得的资源,在未使用完之前,不能强行剥夺
4.循环等待条件:若干进程之间形成一种头尾详见的循环等待资源关系
Lock锁的使用方法
package 多线程.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class TestLock {
public static void main(String[] args) {
BuyTicket bt = new BuyTicket();
new Thread(bt).start();
new Thread(bt).start();
new Thread(bt).start();
}
}
class BuyTicket implements Runnable{
//票数
private int Ticket = 15;
private final ReentrantLock lock = new ReentrantLock();
@Override
public void run() {
while (true){
lock.lock();
if (Ticket > 0){
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
Ticket--;
System.out.println("当前票数:" + Ticket);
}
else{
break;
}
lock.unlock();
}
}
}