代码三些--多线程
一. 网图下载
package com.chen.Thread.Demo01;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
//练习Thread,实现多线程同步下载图片
public class TestThred02 extends Thread{
private String url;//网络图片地址
private String path;//保存的文件名
public TestThred02(String url,String path){
this.url= url;
this.path = path;
}
//下载图片线程的执行体
@Override
public void run() {
WebDownloader webDownloader = new WebDownloader();
webDownloader.downloader(url,path);
System.out.println("图片下载到:"+path);
}
public static void main(String[] args) {
TestThred02 testThred02 = new TestThred02("https://img01.hua.com/uploadpic/newpic/9012452.jpg","d:/g/g.jpg");
testThred02.start();
}
}
//下载器
class WebDownloader{
public void downloader(String url,String path){
try {
FileUtils.copyURLToFile(new URL(url),new File(path));
} catch (IOException e) {
e.printStackTrace();
System.out.println("IO异常,downloader方法出现问题");
}
}
}
二.龟兔赛跑
package com.chen.Thread.Demo01;
//模拟龟兔赛跑
public class Race implements Runnable{
//胜利者
private static String winner;
@Override
public void run() {
for (int i = 0; i <= 100; i++) {
System.out.println(Thread.currentThread().getName()+"跑了"+i+"步");
//判断比赛是否结束
boolean flag = gameOver(i);
//如果比赛结束了,就停止程序
if (flag){
break;
}
//模拟兔子速度更快但是睡觉了
if(Thread.currentThread().getName().equals("兔子")){
if (i==80){//终点前睡觉
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
i+=4;//兔子速度为乌龟五倍
}
}
}
//判断是否完成比赛
private boolean gameOver(int steps){
//判断是否有胜利者
if(winner!=null){
return true;//已经存在胜利者了
}{
if (steps==100){
winner = Thread.currentThread().getName();
System.out.println("winner是"+winner);
return true;
}
}
return false;
}
public static void main(String[] args) {
Race race = new Race();
new Thread(race,"兔子").start();
new Thread(race,"乌龟").start();
}
}
三.线程停止
package com.chen.State;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
//测试stop
//1.建议线程正常停止-->利用次数,不建议死循环
//2.建议使用标志位-->设置一个标志位
//3.不要使用stop或者destroy等过时或者JDK不建议使用的方法
public class TestStop implements Runnable{
//设置一个标志位
private boolean flag = true;
@Override
public void run() {
int i = 0;
while (flag){
System.out.println("run...Thread"+i++);
}
}
//设置一个公开的方法停止线程,转换标识位
public void stop(){
this.flag= false;
}
public static void main(String[] args) {
TestStop testStop = new TestStop();
new Thread(testStop).start();
for (int i = 0; i < 1000; i++) {
System.out.println("main"+i);
if (i==900){
//调用自己写的stop方法,让线程停止
testStop.stop();
System.out.println("线程该停止了");
}
}
}
}
四.模拟倒计时和打印当前时间
package com.chen.State;
import java.text.SimpleDateFormat;
import java.util.Date;
//模拟倒计时
public class TestSleep02 {
public static void main(String[] args) {
// try {
// tendowm();
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
//打印系统当前时间
Date startTime = new Date(System.currentTimeMillis());//获取系统当前时间
while (true){
try {
Thread.sleep(1000);
System.out.println(new SimpleDateFormat("HH:mm:ss").format(startTime));
startTime = new Date(System.currentTimeMillis());//更新系统当前时间
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void tendowm() throws InterruptedException {
int num = 10;
while (true){
Thread.sleep(1000);
System.out.println(num--);
if (num<=0){
break;
}
}
}
}
五.插队
package com.chen.State;
//测试join方法//想象为插队
public class TestJoin implements Runnable{
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println("线程vip来了"+i);
}
}
public static void main(String[] args) throws InterruptedException {
//启动我们的线程
TestJoin testJoin = new TestJoin();
Thread thread = new Thread( testJoin);
thread.start();
//主线程
for (int i = 0; i < 500; i++) {
if (i==200){
thread.join();//插队
}
System.out.println("main"+i);
}
}
}
六.同步方法
package com.chen.syn;
//不安全的取钱
//两个人去银行取钱,账户
public class UnsafeBank {
public static void main(String[] args) {
//账户
Account account = new Account(100,"结婚基金");
Drawing you = new Drawing(account,50,"你");
Drawing girlFriend = new Drawing(account,100,"girlFriend");
you.start();
girlFriend.start();
}
}
//账户
class Account{
int money;//余额
String name;//卡名
public Account(int money, String name) {
this.money = money;
this.name = name;
}
}
//银行:模拟取款
class Drawing extends Thread{
Account account;//账户
//取了多少钱
int drawingMoney;
//现在手里有多少钱
int nowMoney;
public Drawing(Account account,int drawingMoney,String name){
super(name);
this.account = account;
this.drawingMoney = drawingMoney;
}
@Override
public void run() {
synchronized (account){
//判断有没有钱
if (account.money-drawingMoney<0){
System.out.println(Thread.currentThread().getName()+"钱不够,取不了");
return;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
account.money = account.money - drawingMoney;
nowMoney = nowMoney + drawingMoney;
System.out.println(account.name+"余额为"+account.money);
//Thread.currentThread().getName()=this.getName()
System.out.println(this.getName()+"手里的钱"+nowMoney);
}
}
}
6.死锁
package com.chen.Thread;
//死锁:多线程互相抱着对象需要的资源,然后形成僵直
public class DeadLock {
public static void main(String[] args) {
Makeup g1 = new Makeup(0,"灰姑娘");
Makeup g2 = new Makeup(1,"白雪公主");
g1.start();
g2.start();
}
}
//口红
class Lipstick{
}
//镜子
class Mirror{
}
class Makeup extends Thread{
//需要的资源只有一份,用static来保证只有一份
static Lipstick lipstick = new Lipstick();
static Mirror mirror = new Mirror();
int choice;//选择
String girlName;//使用化妆品的人
Makeup(int choice,String girlName){
this.choice = choice;
this.girlName = girlName;
}
@Override
public void run() {
//化妆
try {
makeup();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//化妆,互相持有对方的锁,就是需要拿到对方的资源
private void makeup() throws InterruptedException {
if (choice==0){
synchronized (lipstick){//获得口红的锁
System.out.println(this.girlName+"获得口红的锁");
Thread.sleep(1000);
synchronized (mirror){//一秒钟后想获得镜子
System.out.println(this.girlName+"获得镜子的锁");
}
}
}else {
synchronized (mirror){//获得镜子的锁
System.out.println(this.girlName+"获得镜子的锁");
Thread.sleep(2000);
synchronized (lipstick){//两秒钟后想获得口红
System.out.println(this.girlName+"获得口红的锁");
}
}
}
}
}
7.Reentrantlock
package com.chen.Thread.gaoji;
import java.util.concurrent.locks.ReentrantLock;
//测试Lock锁
public class TestLock {
public static void main(String[] args) {
TestLock02 testLock02 = new TestLock02();
new Thread(testLock02).start();
new Thread(testLock02).start();
new Thread(testLock02).start();
}
}
class TestLock02 implements Runnable{
int tickets = 10;
//定义lock锁
private final ReentrantLock lock = new ReentrantLock();
@Override
public void run() {
while (true){
try{
lock.lock();//加锁
if (tickets>0){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(tickets--);
}else {
break;
}
}finally {
//解锁
lock.unlock();
}
}
}
}
8.管程法(生产者消费者模式)
package com.chen.Thread.gaoji;
//测试:生产者消费者模型-->利用缓冲区解决:管理法
//生产者,消费者,产品,缓冲区
public class TestPC {
public static void main(String[] args) {
SynContainer container = new SynContainer();
new Productor(container).start();
new Consumer(container).start();
}
}
//生产者
class Productor extends Thread{
SynContainer container;
public Productor(SynContainer container){
this.container = container;
}
//生产
@Override
public void run() {
for (int i = 0; i < 100; i++) {
container.push(new Chicken(i));
System.out.println("生产了"+i+"只鸡");
}
}
}
//消费者
class Consumer extends Thread{
SynContainer container;
public Consumer(SynContainer container){
this.container = container;
}
//消费
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("消费了-->"+container.pop().id+"只鸡");
}
}
}
//产品
class Chicken{
int id;//产品编号
public Chicken(int id) {
this.id = id;
}
}
//缓冲区
class SynContainer{
//需要一个容器大小
Chicken[] chickens = new Chicken[10];
//容器计数器
int count = 0;
//生产者放入产品
public synchronized void push(Chicken chicken){
//如果容器满了,就需要等待消费者消费
if (count== chickens.length){
//通知消费者消费,生产等待
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//如果没有满,我们就需要丢入产品
chickens[count] = chicken;
count++;
//可以通知消费者消费了
this.notifyAll();
}
//消费者消费产品
public synchronized Chicken pop(){
//判断能否消费
if (count==0){
//等待生产者生产,消费者等待
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//如果可以消费
count--;
Chicken chicken = chickens[count];
//吃完了,通知生产者生产
this.notifyAll();
return chicken;
}
}