线程的第一种方法:Thread继承。该子类应重写父类中的run方法。
jvm启动不止一个线程,还有负责垃圾回收机制的线程。
覆写run方法的目的:将自定义代码存储在run方法中,让线程运行。
public static void main(String[] args) {
Demo d = new Demo();//创建好一个线程
d.start();//开启线程并执行线程中的run方法。
//d.run();仅仅是对象调用方法,而线程创建了并未运行。
System.out.println("hello world");
}
}
class Demo extends Thread{
public void run() {
System.out.println("run");
}
}
static Thread currentThread():获取当前线程对象。
getName():获取线程名称。
设置线程名称:setName或者构造函数。
练习多线程买票的列子:
public static void main(String[] args) {
Ticket t1 = new Ticket();
Ticket t2 = new Ticket();
Ticket t3 = new Ticket();
Ticket t4 = new Ticket();
t1.start();//不能写t1.run();如果写了只是调用了普通的run方法。
t2.start();
t3.start();
t4.start();
}
}
class Ticket extends Thread{
private static int tick=100;//为什么要写static因为四个线程只用一个对象。
public void run() {
while(true) {
if(tick > 0) {
System.out.println(Thread.currentThread().getName()+" sale :"+ tick--);
//Thread.currenthread().getName()获取线程的名称
}
}
}
}
多线程第二种方法:
Runable:接口应该由那些打算通过某一线程执行其实例的类来实现。类必须定义一个称为run的无参数方法。
实现方式和继承方式有什么区别呢?
实现方式好处:避免了单继承的局限性。在定义线程时,建立使用实现方式。
继承Thread类:线程代码存在Thread子类run方法中。
实现Runnable:线程代码存放在接口的子类的run方法中。
public static void main(String[] args) {
Ticket t = new Ticket();
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
Thread t3 = new Thread(t);
Thread t4 = new Thread(t);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class Ticket implements Runnable{//extends Thread
private static int tick=100;
public void run() {
while(true) {
if(tick > 0) {
System.out.println(Thread.currentThread().getName()+" sale :"+ tick--);
}
}
}
}
多线程处理方式:
public static void main(String[] args) {
Ticket t = new Ticket();
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
Thread t3 = new Thread(t);
Thread t4 = new Thread(t);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class Ticket implements Runnable{//extends Thread
private static int tick=300;
Object obj = new Object(); //上帝类
public void run() {
while(true) {
synchronized(obj) { //多线程处理固定语句
if(tick > 0) {
try {Thread.sleep(10);}catch(Exception e) {}
System.out.println(Thread.currentThread().getName()+" sale :"+ tick--);
}
}
}
}
}
多线程同步代码块:
多线程(同步函数):
问题:两个人去银行存钱每次存1,循环三次。
public static void main(String[] args) {
Cus c=new Cus();
Thread t1=new Thread(c);
Thread t2=new Thread(c);
t1.start();
t2.start();
}
}
class Bank{
private int sum;
Object obj = new Object();//不能写在方法内,因为每次都会重新创建Object对象不能达到公用的效果
public void add(int n){
synchronized(obj) {
sum = sum + n;
try {Thread.sleep(10);}catch(Exception e){}
System.out.println(Thread.currentThread().getName()+" sum="+sum);
}
}
}
class Cus implements Runnable{
private Bank b = new Bank();
public void run()
{
for(int x = 0; x<3; x++)
{
b.add(1);
}
}
}
简易写法把同步放到函数方法上:
public void synchronied run{
方法体
}
public static void main(String[] args) {
Ticket t = new Ticket();
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
t1.start();
try{Thread.sleep(10);}catch(Exception e) {}
t.flag=false;
t2.start();
}
}
class Ticket implements Runnable{
private int tick=100;
Object obj = new Object();
boolean flag=true;
public void run() {
if(flag) {
while(true) {
synchronized(this) {//验证是this
if(tick > 0) {
try{Thread.sleep(10);}catch(Exception e){}
System.out.println(Thread.currentThread().getName()+"...code : "+tick--);
}
}
}
}
else {
while(true) {
show();
}
}
}
public synchronized void show() {
if(tick > 0) {
try{Thread.sleep(10);}catch(Exception e){}
System.out.println(Thread.currentThread().getName()+"...code : "+tick--);
}
}
}
public static void main(String[] args) {
Ticket t = new Ticket();
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
t1.start();
try{Thread.sleep(10);}catch(Exception e) {}
t.flag=false;
t2.start();
}
}
class Ticket implements Runnable{
private static int tick=100;
boolean flag=true;
public void run() {
if(flag) {
while(true) {
synchronized(Ticket.class) {
if(tick > 0) {
try{Thread.sleep(10);}catch(Exception e){}
System.out.println(Thread.currentThread().getName()+"...code : "+tick--);
}
}
}
}
else {
while(true) {
show();
}
}
}
public static synchronized void show() {
if(tick > 0) {
try{Thread.sleep(10);}catch(Exception e){}
System.out.println(Thread.currentThread().getName()+"...code : "+tick--);
}
}
}
死锁:同步中嵌套同步。
public static void main(String[] args) {
Ticket t = new Ticket();
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
t1.start();
try{Thread.sleep(10);}catch(Exception e) {}
t.flag=false;
t2.start();
}
}
class Ticket implements Runnable{
private int tick=500;
Object obj = new Object();
boolean flag=true;
public void run() {
if(flag) {
while(true) {
synchronized(obj) {//原本是this 改为obj
show();
}
}
}
else {
while(true) {
show();
}
}
}
public synchronized void show() {
synchronized (obj){
if(tick > 0) {
try{Thread.sleep(10);}catch(Exception e){}
System.out.println(Thread.currentThread().getName()+"...code : "+tick--);
}
}
}
}
ab锁练习:
public static void main(String[] args) {
Thread t1 = new Thread(new Test(true));
Thread t2 = new Thread(new Test(false));
t1.start();
t2.start();
}
}
class Test implements Runnable{
private boolean flag;
//static Object looka=new Object();
//static Object lookb=new Object();
Test(boolean flag){
this.flag=flag;
}
public void run() {
if(flag)
{
synchronized(MyLock.looka) {
System.out.println("a-b");
synchronized(MyLock.lookb) {
System.out.println("a--b");
}
}
}
else {
synchronized(MyLock.lookb) {
System.out.println("b-a");
synchronized(MyLock.looka) {
System.out.println("b--a");
}
}
}
}
}
class MyLock{//新建一个类只为了确保使用的是同一个锁
static Object looka = new Object();
static Object lookb = new Object();
}