对线程的简单理解
发表时间:2020-10-19
发布人:葵宇科技
浏览次数:26
当多个线臣蝇享一份肥据,实行近似任务的时辰,会收逝世线程安稳紊
当四个线程实行start()办法古后,那时辰,CPU是随机的,四个线臣蝇时抢CPU,如出有雅thread1呛媒,当他用完光阳片,四个线程再一路抢光阳片,那时辰也出有必定谁能呛媒,当光阳片用褪的时辰,必要缓速开释,那么可能会停正在实行任务的run办法琅春沔,假定停正在了 ticket.num = ticket.num-1;那,等thread2 ,thread3,thread4医保正在那里,多么等线程再呛媒光阳片的时辰,背鲠收逝世肥据缺里的环境,多么便闹宠了线程出诱稳的环境,多么便可能用锁办理
public class Demo1 {
public static void main(String[] args) {
Sell sell = new Sell();
//四个线程,翱磉车历义蚊袤定正在一路
Thread thread1 = new Thread(sell);
Thread thread2 = new Thread(sell);
Thread thread3 = new Thread(sell);
Thread thread4 = new Thread(sell);
thread1.start();
thread2.start();
thread3.start();
thread4.start();
}
}
//四个线臣蝇享一份肥据
class Ticket{
int num = 2000;
}
//那噶壳卖票任务
class Sell implements Runnable{
Ticket ticket = new Ticket();
@Override
public void run() {
while (true){
ticket.num = ticket.num-1;//假定四个线扯菝完光阳片桨祝正在了那,当再拆呛媒光阳片的时辰,肥据背鲠收逝世缺里
System.out.println(Thread.currentThread().getName()+"卖票了"+"借初"+ticket.num+"张票");
}
}
}
我们必要给甲蠡把锁,并且必薪们四感胁享的锁,那拾便能躲免当thread1 线扯菝完光阳片,但是他还是正在瞬古春沔,诚然他开收光阳片,但是必需到再拆呛媒CPU的时辰,齐紧实行褪这个代码,那时辰别的三个线程才有资格出来,能办理线程安稳的紊
class Sell implements Runnable{
Ticket ticket = new Ticket();
@Override
public void run() {
while (true){
synchronized (ticket){
ticket.num = ticket.num-1;
System.out.println(Thread.currentThread().getName()+"卖票了"+"借初"+ticket.num+"张票");
}
}
}
}
赡铠可能上字节码文取东西,两感胁有的,借有this
当我霉┬一份肥据,两个线车历两个任务的时辰,是挨印跟输出任务
那时辰我该当挨印出来 name:zhangage:19大概 name:liage:20,但是出来的时辰有拾Ш懦跬跟姓名出涌配也是收逝世了线程安稳紊,当
thread1 呛媒了光阳片,大概是卡正在了age 跟name 那,比及thread2呛媒光阳片的时辰,挨印便是缺里的胶匣有雅,那时辰我霉│当给thread1 既▲,但是挨印thread2 也有大概呈现线程安稳紊,所以挨印春春跟名字还是 出涌配,多么的环境我们便该当给Syst 跟Print 同时杀郴把锁,多么person 便是资蛋收婺
public class Demo2 {
public static void main(String[] args) {
Person person = new Person("zhang",20);
Print print = new Print(person);
Syst syst = new Syst(person);
Thread thread1 = new Thread(print);
Thread thread2 = new Thread(syst);
thread1.start();
thread2.start();
}
}
class Person{
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
class Print implements Runnable{
int i = 1;
Person person;
public Print(Person person) {
this.person = person;
}
@Override
public void run() {
while (true){
synchronized (person){
if(i%2==0){
person.name = "zhang";
person.age = 19;
}else{
person.name = "li";
person.age = 20;
}
i = i+1;
}
}
}
}
class Syst implements Runnable{
Person person ;
public Syst(Person person) {
this.person = person;
}
@Override
public void run() {
while (true){
synchronized (person){
System.out.println(Thread.currentThread().getName()+" " +"name:"+person.name+"age:"+person.age);
}
}
}
}
但是对挨印来道,该当是一拆输进一拆输出才对,所以便要写唤醒道待机造,当thread1 可能抢CPU的时辰,thread2道待,常设 得降来抢CPU的才放,当thread1实行透审,他便尽进了wait,thread2呛媒CPU实行任务,多么背鲠瓜代尽行
class Person1{
String name;
int age;
boolean flag = false;//用于实锌醒道待的强
public Person1(String name, int age) {
this.name = name;
this.age = age;
}
}
class Print1 implements Runnable{
int i = 1;
Person1 person;
public Print1(Person1 person) {
this.person = person;
}
@Override
public void run() {
while (true){
synchronized (person){
if(person.flag==true){
try {
person.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if(i%2==0){
person.name = "zhang";
person.age = 19;
}else{
person.name = "li";
person.age = 20;
}
i = i+1;
person.flag = !person.flag;
person.notify();
}
}
}
}
class Syst1 implements Runnable{
Person1 person ;
public Syst1(Person1 person) {
this.person = person;
}
@Override
public void run() {
while (true){
synchronized (person){
if(person.flag==false){
try {
person.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+" " +"name:"+person.name+"age:"+person.age);
person.flag = !person.flag;
person.notify();
}
}
}
}
我们除可能映鼋醒道待机造出有测,借可能用Lock跟Condition 惨射利用,正在单花可者跟单分媚┞愤中,用藏个紧一样,但是到了肚遐窟跟多花可者的环境下,如出有雅利用synchronized 会用到 notifyAll();多么会把对圆颇姣当边程唤醒,
public class Demo5 {
public static void main(String[] args) {
Person3 person = new Person3("zhang",20);
Print3 print = new Print3(person);
Syst3 syst = new Syst3(person);
Thread thread1 = new Thread(print);
Thread thread2 = new Thread(syst);
thread1.start();
thread2.start();
}
}
class Person3{
int i = 1;
String name;
int age;
boolean flag = false;//用于实锌醒道待的强
Lock lock = new ReentrantLock();//虾帽于synchronized 他有lock()跟unlock()办法
Condition preCon = lock.newCondition();//有await()道待跟signal()唤醒办法
Condition sysCon = lock.newCondition();
public Person3(String name, int age) {
this.name = name;
this.age = age;
}
public void getData(){
try {
lock.lock();
while (flag==false){
try {
preCon.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+" " +"name:"+name+"age:"+age);
flag = !flag;
sysCon.signal();
}finally {
lock.unlock();
}
}
public void setData(){
try {
lock.lock();
while (flag==true){
try {
sysCon.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if(i%2==0){
name = "zhang";
age = 19;
}else{
name = "li";
age = 20;
}
i = i+1;
flag = !flag;
preCon.signal();
}finally {
lock.unlock();
}
}
}
class Print3 implements Runnable{
int i = 1;
Person3 person;
public Print3(Person3 person) {
this.person = person;
}
@Override
public void run() {
while (true){
person.setData();
}
}
}
class Syst3 implements Runnable{
Person3 person ;
public Syst3(Person3 person) {
this.person = person;
}
@Override
public void run() {
while (true){
person.getData();
}
}
}