JavaSE06

14 篇文章 0 订阅
package day06;
/**
 * 并发原理
 * 多线程:多线程允许我们“同时”执行多段代码
 * 
 * 线程是并发运行的,线程调度会统一规划CPU时间,将CPU的时间划分为若干片段,然后
 * 尽可能的均匀分配给所有要并发的线程,每个线程在获取CPU时间片后,CPU就来运行它的任务,
 * 当时间片段用完后,CPU会离开并执行获取CPU时间片的线程,所以所有线程并非
 * 真正的“同时”运行这代码。而是走走停停,这种微观上的走走停停,宏观上感觉是同时运行的现象
 * 称之为并发运行。
 * 
 * 线程提供了两种创建方式
 * 方式一:
 * 继承Thread并重写run方法来定义线程任务
 * @author 臻冉
 *
 */
public class ThreadDemo {
	public static void main(String[] args) {
		Thread t = new MyThread1();
		
		Thread t1 =new MyThread2();
		/*
		 * 注意:启动线程不是调用run()方法,而是调用start()方法
		 * 线程开始并发运行时,会自动调用run()方法。
		 */
		t.start();
		t1.start();
	}
}

/*
 * 第一种创建线程的方式有两个不足:
 * 1.由于java是单继承,这就导致了若继承了Thread就不能再继承其他类
 * 在实际开发中非常不方便,因为无法重用其他类的方法
 * 2.由于继承Thread后重写run方法定义了线程要执行的任务,这就导致了线程
 * 与线程执行的任务有一个必然的耦合关系,不利于线程的重用
 */


class MyThread1 extends Thread{
	public void run(){
		for(int i=0;i<100;i++){
			System.out.println("你好,我是张翠花!");
		}
	}
}

class MyThread2 extends Thread{
	public void run(){
		for(int i=0;i<100;i++){
			System.out.println("你好,我是赵狗蛋!嘻嘻...");
		}
	}
}
package day06;
/**
 * 第二种创建线程的方式:
 * 实现Runnable接口单独定义线程任务
 * 
 * 使用Runnable创建并启动线程:
 * 实现Runnable接口并重写run方法来定义线程体,然后再创建线程的时候
 * 将Runnable的实列传入并启动线程;
 * 
 * 这样做的好处在于可以将线程与线程要执行的任务分离并减少耦合度定义一个类实现Runnable接口,
 * 定义一个类实现Runnable接口,这样的作法可以更好的去实现其他父类或接口(接口是多继承关系)

 */
public class ThreadDemo02 {
	public static void main(String[] args) {
		//创建任务
		Runnable r = new MyThread3();
		Runnable r2 = new MyThread4();
		
		//创建线程
		Thread t = new Thread(r);
		Thread t2 = new Thread(r2);
		t.start();
		t2.start();
	}
}



class MyThread3 implements Runnable{

	public void run() {
		for(int i=0;i<100;i++){
			System.out.println("我是翠花,来自西北地区。");
		}
	}
}


class MyThread4 implements Runnable{

	@Override
	public void run() {
		for(int i=0;i<100;i++){
			System.out.println("你好,我是狗蛋,来自新疆");
		}
	}
}


package day06;
/**
 * 用匿名内部类形式完成线程的两种创建方式
 * @author 臻冉
 *
 */
public class ThreadDemo03 {
	public static void main(String[] args) {
		//方式一:匿名内部类直接创建Thread
		Thread t = new Thread(){
			public void run(){
				for(int i=0;i<100;i++){
					System.out.println("李狗蛋,你好,我是张翠花。");
				}
			}
		};
		
		//方式二:匿名内部类创建Runnable,再由线程运行
		Runnable r = new Runnable(){
			public void run(){
				for(int i=0;i<100;i++){
					System.out.println("翠花,我...我,你好,我是狗蛋..");
				}
			}
		};
		Thread th = new Thread(r);
		t.start();
		th.start();
	}
}

package day06;
/**
 * 线程提供了一个静态方法:
 * static Thread currentThread()
 * 该方法可以获取运行这个方法的线程
 * java中所有的代码都是线程运行的,main方法也不例外
 * JVM启动后会启动一个线程来执行main方法,通常我们成执行main
 * 方法的线程为“主线程”。
 * @author 臻冉
 *
 */
public class CurrentThreadDemo05 {
	public static void dosome(){
		Thread t = Thread.currentThread();
		System.out.println("运行dosome方法的线程是:"+t);
	}
	public static void main(String[] args) {
		Thread main = Thread.currentThread();
		/*
		 * Thread[main,5,main]
		 * [线程名字,优先级别]
		 */
		System.out.println(main);
		
		Thread t2 = new Thread(){
			public void run(){
			Thread t = Thread.currentThread();
			System.out.println("自定义线程:"+t);
			dosome();
		}
		};
		
		t2.start();
		
	}
}

package day06;

public class InfoDemo_06 {
	public static void main(String[] args) {
		//获取线程id
		Thread t = Thread.currentThread();
		//获取线程名称
		String name = t.getName();
		System.out.println(name);
		//获取线程的优先级
		int p =t.getPriority();
		System.out.println(p);
		//判断线程是否活着
		boolean b= t.isAlive();
		System.out.println(b);
		//判断线程是否是后台线程(守护线程)
		boolean b1 = t.isDaemon();
		System.out.println(b1);
		//判断线程是否被中断
		boolean b2 = t.isInterrupted();
		System.out.println(b2);
	}
}

package day06;
/**
 * 线程优先级:
 * 线程调用start方法后纳入线程调度统一管理,线程不能主动获取CPU时间片段,只能被动分配;
 * 调整线程优先级可以最大程度的改善某个线程获取CPU时间片段的几率,
 * 理论上线程优先级越高的线程获取的CPU时间片段的次数越多,
 * 
 * 线程优先级有10个等级,用证书1-10表示,1最低,5默认,10最高
 * @author 臻冉
 *
 */
public class ProiorityDemo_07 {
	public static void main(String[] args) {
		Thread t = new Thread(){
			public void run(){
				for(int i=0;i<1000;i++){
					System.out.println("max");
				}
			}
		};
		
		Thread t2 = new Thread(){
			public void run(){
				for(int i=0;i<1000;i++){
					System.out.println("nor");
				}
			}
		};
		
		Thread t3 = new Thread(){
			public void run(){
				for(int i=0;i<1000;i++){
					System.out.println("min");
				}
			}
		};
		t.setPriority(Thread.MAX_PRIORITY);
		t3.setPriority(Thread.MIN_PRIORITY);
		
		t.start();
		t2.start();
		t3.start();
		
	}
}

package day06;
/**
 * sleep睡眠阻塞
 * static void sleep(long ms)
 * 当一个线程执行sleep方法后就会进去阻塞状态指定的毫秒数,
 * 超过后线程会自动回到Runnable 状态等待再次并发运行,该方法要求
 * 必须处理InterruptedException。即,当一个线程处于睡眠阻塞时
 * 被其他线程调用interrupted方法中断时会抛出该终端异常并打开睡眠阻塞
 * @author 臻冉
 *
 */
public class SleepBlockDemo_08 {
	public static void main(String[] args) {
		/*Thread t = new Thread(){
			public void run(){
				try {
					System.out.println("等待时间为3s");
					Thread.sleep(3000);
					System.out.println("结果出来了!");
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		};
		t.start();*/
		//第一个线程阻塞:sleep(10000)
		//第二个线程阻塞:sleep(1000)		//循环5次   interrupted()
		
		Thread lin = new Thread(){
			public void run(){
				System.out.println("林:刚美容完,睡一会儿吧...");
				try {
					Thread.sleep(10000);
				} catch (InterruptedException e) {
					System.out.println("林:干嘛呢,干嘛呢,都破了相了..");
				}
				
			}
		};
		
		
		Thread huang = new Thread(){
			public void run(){
				System.out.println("黄:我开始砸墙了...");
				for(int i=0;i<5;i++){
					System.out.println("黄:80");
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				System.out.println("黄:咣当,搞定啦!");
				lin.interrupt();	//中断lin线程
			}
		};
		
		lin.start();
		huang.start();
	}
}

package day06;

import java.awt.Color;

import javax.swing.JFrame;
import javax.swing.JPanel;

/**
 * 使用睡眠阻塞方式实现图片切换
 * @author 臻冉
 *
 */
public class SleepBlockDemo_09 {
	public static void main(String[] args) {
		JFrame frame = new JFrame();//窗口
		frame.setSize(550,500);
		JPanel panel = new JPanel();//面板
		panel.setSize(500,500);
		frame.setContentPane(panel);
		frame.setVisible(true);//是否可见
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setLocationRelativeTo(null);//居中
		Thread t = new Thread(){
			public void run(){
				int i=0;
				while(true){
					i = i==0?1:0;
					if(i==0){
						//设置图片颜色为Green
						panel.setBackground(Color.BLACK);
					}
					
					if(i==1){
						//设置图片颜色Red
						panel.setBackground(Color.PINK);
					}
					try {
						Thread.sleep(2000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		};
		t.start();
	}
}

package day06;
/**
 * 守护线程:
 * 守护线程又称为后台线程,默认创建的线程都不是守护线程
 * 守护线程需要调用线程提供的方法设置
 * void setDaamon(Boolean b)
 * 当参数为true时,线程变为守护线程;
 * 
 * 守护线程使用与普通线程没区别,但是结束时有一个区别;
 * 	当进程结束时,所有正在运行的守护线程会强制结束,也就是
 * 	普通线程结束了,守护线程强制终止。
 * @author 臻冉
 *
 */
public class DaemoThreadDemo_10 {
	public static void main(String[] args) {
		Thread rose = new Thread(){
			public  void run(){
				for(int i=0;i<5;i++){
					System.out.println("rose:let me go!");
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				System.out.println("rose:啊啊啊....");
				System.out.println("噗通..");
				
			}
		};
		
		Thread jack = new Thread(){
			public void run(){
				while(true){
					System.out.println("jack:you jump,I jump");
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		};
		jack.setDaemon(true);		//设置守护线程,注意:在start方法调用Ian设置
		rose.start();
		jack.start();
		System.out.println("我是'主线程main'");
		
		
		
	}
}

package day06;
/**
 * 线程提供了一个方法
 * void join()
 * 该方法欲奴一个线程在另一个线程上等待,直到其执行完毕后再继续执行,
 * 这样做可以协调线程之间的“同步”
 * 
 * 同步运行:代码执行由先后顺序(单线程运行是同步的,多线程也可以今次那个同步运行操作)
 * 异步运行:代码各执行隔得(多线程下代码运行是异步的)
 * @author 臻冉
 *
 */
public class JoinDemo_11 {
	public static void main(String[] args) {
		//下载线程
		Thread download = new Thread(){
			public void run(){
				try {
					System.out.println("电影开始下载...");
					for(int i=0;i<100;i++){
						System.out.println("下载进度"+i+"%");
						Thread.sleep(50);
					}
					System.out.println("图片下载完毕!");
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				
			}
		};
		
		//显示线程
		Thread  show = new Thread(){
			public void run(){
				try {
					download.join();
					System.out.println("开始播放电影!:");
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				
				
			}
		};
		download.start();
		show.start();
	}
}

package day06;

import javax.management.RuntimeErrorException;

/**
 * 多线程并发安全问题:
 * 当多个线程并发运行操作统一数据是时,由于线程切换的时机不可控制,
 * 可能导致操作该数据时的过程未按照程序设计的执行时顺序运行导致
 * 操作出现混乱,严重时可能会导致系统瘫痪。
 * @author 臻冉
 *
 */
public class SyncDemo_12 {
	public static void main(String[] args) {
		Table table = new Table();
		
		Thread t1 = new Thread(){
			public void run(){
				while(true){
					int b = table.getBean();
					Thread.yield();//模拟线程切换
					System.out.println(getName()+":"+b);
				}
			}
		};
		
		Thread t2 = new Thread(){
			public void run(){
				while(true){
					int b1 = table.getBean();
					Thread.yield();//模拟线程切换
					System.out.println(getName()+":"+b1);
				}
			}
		};
		t1.start();
		t2.start();
	}
}

class Table{
	private int bean = 20;
	
	/*
	 * yield()方法作用是:暂停当前正在执行的线程对象(放弃当前拥有的CPU资源),
	 * 并执行其他线程
	 * 
	 * yield()让当前运行线程回到可运行状态,以允许具有相同优先级的其他线程
	 * 获得运行机会,但是有可能效果没用
	 */
	
	/*
	 * 当一个方法用synchronized修饰后,那么该方法变为“同步方法”多个线程
	 * 不能同时进入方法运行,而必须有顺序的一个一个运行这样就避免了并发安全问题
	 */
	public synchronized int getBean(){
		if(bean == 0){
			throw new RuntimeException("没有豆子了!");
		}
		Thread.yield();//模拟线程切换
		return bean--;
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值