一.实现线程的两种方式
1.继承Thread,重写run()方法
创建
package Test;
/**
* 线程学习代码
*/
public class ThreadStudy extends Thread{
private String na;
public ThreadStudy(){
}
public ThreadStudy(String na){
this.na = na;
}
public String getNa() {
return na;
}
public void setNa(String na) {
this.na = na;
}
public void run(){
for (int i = 0; i <100 ; i++) {
System.out.println(this.getNa()+"跑了"+i+"多少米");
}
}
}
调用
package Test;
public class Test {
public static void main(String[] args) {
ThreadStudy ts1=new ThreadStudy("加特林");
ThreadStudy ts3=new ThreadStudy("舒伯特");
ThreadStudy ts2=new ThreadStudy("留下");
ts1.start();
ts2.start();
ts3.start();
}
}
2.实现runnable()接口
创建
package Test;
/**
* 线程学习代码
*/
public class ThreadStudy implements Runnable{
private String na;
public ThreadStudy(){
}
public ThreadStudy(String na){
this.na = na;
}
public String getNa() {
return na;
}
public void setNa(String na) {
this.na = na;
}
public void run(){
for (int i = 0; i <100 ; i++) {
System.out.println(this.getNa()+"跑了"+i+"多少米");
}
}
}
调用
package Test;
public class Test {
public static void main(String[] args) {
ThreadStudy ts1=new ThreadStudy("加特林");
ThreadStudy ts3=new ThreadStudy("舒伯特");
ThreadStudy ts2=new ThreadStudy("留下");
Thread t1=new Thread(ts1);
Thread t2=new Thread(ts2);
Thread t3=new Thread(ts3);
t1.start();
t2.start();
t3.start();
}
}
3.线程的几种状态,及如何切换
创建对象----就绪状态----执行状态----等待/挂起----异常/消亡
new------start-------run ----- wait--------exception
二.简单的练习(模拟一个12306)
1.创建一个包2.代码
package simulation12306;
import java.util.Vector;
public class System12306 {
private Vector<Ticket> tickets=new Vector<>();
//设计一个单例(恶汉模式)
private System12306(){}
private static System12306 system12306=new System12306();
public static System12306 getinstance(){
//懒汉模式在里面new
return system12306;
}
//给tickets赋值
{
for (int i = 10; i <100 ; i++) {
tickets.add(new Ticket("北京"+i,"深圳",(i%5+5)*25f));
}
}
public Ticket getTicket(){
if(tickets.isEmpty()){
return null;
}else {
return tickets.remove(0);
}
}
}
package simulation12306;
public class Testmain {
public static void main(String[] args) {
Window w1=new Window("窗口1");
Window w2=new Window("窗口2");
Window w3=new Window("窗口3");
Window w4=new Window("窗口4");
w1.start();
w2.start();
w3.start();
w4.start();
}
}
package simulation12306;
public class Window extends Thread{
private String windowName;
public Window(){
}
public Window(String windowName){
this.windowName=windowName;
}
public void run(){
sellTicket();
}
public void sellTicket(){
System12306 ss=System12306.getinstance();
while (true){
Ticket ticket=ss.getTicket();
if(ticket==null){
System.out.println(windowName+"窗口车票已卖完");
break;
}
System.out.println(this.windowName+"卖出"+ticket.getStart()+"的车票");
}
}
}
package simulation12306;
public class Ticket {
private String start;//起始站
private String end;//终点站
private Float price;//价格
public Ticket(String start,String end,Float price){
this.start = start;
this.end = end;
this.price = price;
}
public Ticket(){
}
public String getStart() {
return start;
}
public void setStart(String start) {
this.start = start;
}
public String getEnd() {
return end;
}
public void setEnd(String end) {
this.end = end;
}
public Float getPrice() {
return price;
}
public void setPrice(Float price) {
this.price = price;
}
}
三.生产消费模型.
1.代码
package producerconsumbermodel;
import java.util.ArrayList;
import java.util.List;
public class Warehouse{
private List<String> list=new ArrayList<>();//线程非安全
public void setList(){
if(list.size()<20){
list.add("aaa");
System.out.println("生产了一个商品");
}else{
return;
}
}
public void getList(){
if(list.size()>0){
list.remove(0);
System.out.println("拿走了一个商品");
}else{
return;
}
}
}
package producerconsumbermodel;
public class Producer extends Thread{
private Warehouse warehouse;
public Producer(){
}
public Producer(Warehouse warehouse) {
this.warehouse = warehouse;
}
public void run(){
while (true){
warehouse.setList();
try {
Thread.sleep(200);
}catch (Exception e){
e.printStackTrace();
}
}
}
}
package producerconsumbermodel;
public class Consumber extends Thread{
private Warehouse warehouse;
public Consumber(Warehouse warehouse) {
this.warehouse = warehouse;
}
public void run(){
while (true){
warehouse.getList();
try {
Thread.sleep(300);
}catch (Exception e){
e.printStackTrace();
}
}
}
}
package producerconsumbermodel;
public class test {
public static void main(String[] args) {
Warehouse w=new Warehouse();
Producer producer=new Producer(w);
producer.start();
Consumber c1=new Consumber(w);
Consumber c2=new Consumber(w);
Consumber c3=new Consumber(w);
c1.start();
c2.start();
c3.start();
}
}
2.线程安全问题
2.1出现的原因
会出现两个异常,一.如上,二.IllegalMonitorStateException非法监听异常
3.解决线程安全的问题(特征修饰符synchronized同步,线程锁)
两种写法:
1.放在方法的结构上public synchronized void test(){}锁定的是调用方法时的那个对象
package producerconsumbermodel;
import java.util.ArrayList;
import java.util.List;
public class Warehouse{
private List<String> list=new ArrayList<>();//线程非安全
public synchronized void setList(){
if(list.size()<20){
list.add("aaa");
System.out.println("生产了一个商品");
}else{
System.out.println("生产满了,等一会再生产");
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void getList(){
if(list.size()>0){
list.remove(0);
System.out.println("拿走了一个商品");
}else{
System.out.println("等你生产");
try {
this.notifyAll();//唤醒所有线程
this.wait();//this指的是调用当前对象的线程等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
2.放在方法内部public void test(){代码synchronized(){代码}代码}锁定的是调用方法时的那个对象
小结.
wait和sleep的区别