多线程:指的是这个程序(一个进程)运行时产生了不止一个线程
并行和并发:
- 并行:多个cpu实例或者多台机器同时执行一段处理逻辑,是真正的同时。
- 并发:通过cpu调度算法,让用户看上去同时执行,实际上从cpu *** 作层面不是真正的同时。并发往往在场景中有公用的资源,那么针对这个公用的资源往往产生瓶颈,我们会用TPS或者QPS来反应这个系统的处理能力。
最基础的主要分为两种方法
- 继承Thread类
- 实现Runnable接口
用这种方法生成新线程,可以按以下步骤进行:
- 定义Thread类的子类
class MyThread extends Thread
- 在子类中重写run方法
- 实例化MyThread,调用start方法开始运行
实例:
public class test1 { public static void main(String[] argv){ testThread t1 = new testThread(); t1.start(); while(true){ try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Thread 2"); } } } class testThread extends Thread{ public void run(){ while(true){ try { sleep(1); }catch (Exception e){ System.out.println(e.getMessage()); } System.out.println("Thread 1"); } } }实现Runnable接口
- 定义一个类MyThread实现Runnable接口
- 实现他的唯一的抽象函数run()
- 实例化MyThead
- 再实例化Thread(MyThread,name)
- 调用start方法
// 用runnable构造线程 public class Book2 { public static void main(String[] argv){ System.out.println("开始"); MyThread2 m1,m2,m3; Thread t1,t2,t3; m1 = new MyThread2(2,70); m2 = new MyThread2(3,70); m3 = new MyThread2(5,70); t1 = new Thread(m1,"A"); t2 = new Thread(m2,"B"); t3 = new Thread(m3,"C"); t1.start(); t2.start(); t3.start(); System.out.println("当前共有"+Thread.activeCount()+"个线程"); System.out.println("Main结束"); } } class MyThread2 implements Runnable{ private int n,max; public MyThread2(int n1,int max1){ n = n1; max = max1; } @Override public void run() { int i = 1; while(n*i<=max){ System.out.println(n*i+" "); i++; } System.out.println(Thread.currentThread().getName()+"结束"); } }其他构造线程的方式
这里还有一个更加灵活的方式去实现线程的构造
主要是思路就是在实现Runnable的时候,在析构方法中就创建Thread的对象,再添加一个start方法
这样在mian方法里面,就可以直接实例化MyThread,直接调用start方法,不需要像第二个方法一样再去创建一个Thread对象
- 创建MyThread类实现Runnable接口
- 在析构方法中实例化Thread对象
- 创建start方法
- 在mian中实例化MyThread,直接调用MyThread类的start开启线程
实例:
public class test2 { public static void main(String[] argv){ System.out.println("开始"); MyThread2 m1,m2; m1 = new MyThread2(1,"第一个"); m2 = new MyThread2(3,"第二个"); m1.start(); m2.start(); System.out.println("当前共有"+Thread.activeCount()+"个线程"); System.out.println("Main结束"); } } class MyThread2 implements Runnable{ private int n; private Thread t; public MyThread2(int n1,String name){ n = n1; t = new Thread(this,name); } //这里不是对Thread类的start方法的重写 public void start(){ t.start(); } @Override public void run() { System.out.println(n); System.out.println(Thread.currentThread().getName()+"结束"); } }线程的互斥
- 由于基本类型难于附加更多机制,因此Java将资源
限定为引用型对象,并为每一对象自动配备一把锁。 - 锁初始时,是处于打开状态。
- synchronized标记的原子代码段在访问资源前,会自动检测资源对象持有的锁是否处于打开状态。如果是,则占用并同时将锁置为锁闭状态。并在该代码段执行完牛后,将锁的状态值设为打开状态。如果自动检测到资源对象持有的锁处于锁闭状态,则持有该代码段的线程因等待资源占用而进入阻塞
- 插入代码块
synchronized(竞争临界资源){原子 *** 作}
- 作为函数的声明
public synchronized void f(){...} 等价于 public void f(){synchronized (this){...} }实例
共享打字机
public class Work1 { public static void main(String[] args){ String flag = "flag"; String[] work1 = {"1","3","5","7","9"}; String[] work2 = {"2","4","6","8","10"}; String[] work3 = {"3","6","9","12"}; Work_1 w1 = new Work_1(flag,"甲",work1); Work_1 w2 = new Work_1(flag,"乙",work2); Work_1 w3 = new Work_1(flag,"丙",work3); w1.start(); w2.start(); w3.start(); } } class Work_1 extends Thread{ private String flag; private String name; private String[] content; public Work_1(String f,String n,String[] c){ flag = f; name = n; content = c; } public void run(){ synchronized (flag){ System.out.print(name+":"); for(String x:content) System.out.print(" "+x); System.out.println(); } } }
多窗口售票
import java.util.Arrays; public class Work3 { public static void main(String[] args){ int[] data = new int[100]; for(int i = 0;i<100;i++){ data[i] = i; } Pos pos = new Pos(data.length); Buy w1 = new Buy(pos,data,"一号"); Buy w2 = new Buy(pos,data,"二号"); Buy w3 = new Buy(pos,data,"三号"); Buy w4 = new Buy(pos,data,"四号"); w1.start(); w2.start(); w3.start(); w4.start(); } } class Buy extends Thread{ private int data[]; private int over[]; private String name; private Pos pos; public Buy(Pos p,int[] d,String n){ pos = p; data = d; name = n; over = new int[data.length]; } public void run(){ while (true){ try { sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (pos){ int x = pos.getPos(); if(x==-1) return; int tic = data[x]; System.out.println(name+"窗口售出"+tic+"号票"); } } } } class Pos{ private int max,pos; public Pos(int m){ max = m; pos=0; } public int getPos(){ if (pos==max) return -1; int x = pos; pos++; return x; } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)